filmreelcontainer.cpp

来自「series60 应用程序开发的源代码 series60 应用程序开发的源代码」· C++ 代码 · 共 493 行

CPP
493
字号
/**
*
* @brief Definition of CFilmReelContainer
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/

// INCLUDE FILES

// Class include
#include "FilmReelContainer.h"

// System includes
#include <aknnavi.h>            // CAknNavigationControlContainer
#include <aknnavide.h>            // CAknNavigationDecorator
#include <aknnavilabel.h>        // CAknNaviLabel
#include <aknnotewrappers.h>    // CAknErrorNote
#include <AknAppUi.h>            // CEikButtonGroupContainer
#include <eikapp.h>                // CEikApplication
#include <palbsettings.h>        // TPAlbSettings
#include <palbimagefactory.h>    // KWidth_VGA && KHeight_VGA
#include <StringLoader.h>        // StringLoader
#include <filmreel.rsg>

// User includes
#include "CameraManager.h"        // CCameraManager
#include "CameraTimer.h"        // CCameraTimer

// CONSTANTS

const TInt KNumberOfPicturesInRow = 4;
const TInt KNumberOfPicturesInColumn = 4;
const TInt KTotalNumberOfPictures = KNumberOfPicturesInRow * KNumberOfPicturesInColumn;
const TInt KHorizontalDistance = KWidth_VGA / KNumberOfPicturesInRow;
const TInt KVerticalDistance = KHeight_VGA / KNumberOfPicturesInColumn;

_LIT(KDefaultFileName, "FilmReel.jpg");

const TInt KJpgSavingQualityFactor = 55; // Quality factor for JPG saving
const TInt KFractionOfFontSizeToLowerText = 3;


// ================= MEMBER FUNCTIONS =======================

/**
* Symbian OS 2nd phase constructor.  Creates a Window for the controls, which it contains.
* Constructs a label and adds it to the window, which it then activates.
* @param aRect The rectangle for this window
*/
void CFilmReelContainer::ConstructL(const TRect& aRect)
{
    iCameraManager = CCameraManager::NewL(*this);
    iBitmap = new (ELeave) CFbsBitmap();
    iCollageBitmap = new(ELeave) CFbsBitmap();
    User::LeaveIfError(iCollageBitmap->Create(TSize(KWidth_VGA, KHeight_VGA), EColor4K));

    iBitmapDevice = CFbsBitmapDevice::NewL(iCollageBitmap);
    User::LeaveIfError(iBitmapDevice->CreateContext(iBGc));

    // Init a file saver utility
    iFileSaver = CMdaImageBitmapToFileUtility::NewL(*this);
    iFormat = new (ELeave) TMdaJfifClipFormat;

    // Camera Timer
    iCameraTimer = CCameraTimer::NewL(*this);

    // Text strings
    iNotReadyText = StringLoader::LoadL(R_NOT_READY_TEXT);
    iTimeOutText = StringLoader::LoadL(R_TIMED_OUT_TEXT);

    // Fetch pointer to the default navi pane control
    CEikStatusPane* sp = ((CAknAppUi*)iEikonEnv->EikAppUi())->StatusPane();
    iNaviPane = (CAknNavigationControlContainer*)sp->ControlL(TUid::Uid(EEikStatusPaneUidNavi));
    iNaviDecoratorForLabel = iNaviPane->ResourceDecorator();

    if (iNaviDecoratorForLabel)
    {
        iNaviLabel=(CAknNaviLabel*)iNaviDecoratorForLabel->DecoratedControl();
        iNaviLabel->SetNaviLabelType(CAknNaviLabel::EAdditionalInfoLabel);
    }

    SetNaviLabelTextL(R_NOT_READY_TEXT);

    CreateWindowL();
    SetRect(aRect);
    ActivateL();
}

/**
* Symbian OS 2 phase constructor.
* Constructs the CFilmReelContainer using the NewLC method, popping
* the constructed object from the CleanupStack before returning it.
*
* @param aRect The rectangle for this window
* @return The newly constructed CFilmReelContainer
*/
CFilmReelContainer* CFilmReelContainer::NewL(const TRect& aRect)
{
    CFilmReelContainer* self = CFilmReelContainer::NewLC(aRect);
    CleanupStack::Pop(self);
    return self;
}

/**
* Symbian OS 2 phase constructor.
* Constructs the CFilmReelContainer using the constructor and ConstructL
* method, leaving the constructed object on the CleanupStack before returning it.
*
* @param aRect The rectangle for this window
* @return The newly constructed CFilmReelContainer
*/
CFilmReelContainer* CFilmReelContainer::NewLC(const TRect& aRect)
{
    CFilmReelContainer* self = new (ELeave) CFilmReelContainer;
    CleanupStack::PushL(self);
    self->ConstructL(aRect);
    return self;
}

/**
* Destructor.  Frees up memory.
*/
CFilmReelContainer::~CFilmReelContainer()
{
    delete iCameraManager;
    delete iBitmap;
    delete iCollageBitmap;
    delete iBGc;
    delete iBitmapDevice;

    delete iFileSaver;
    delete iFormat;

    delete iCameraTimer;

    delete iNotReadyText;
    delete iTimeOutText;

    delete iNaviDecoratorForLabel;
}

/**
* Provides user feedback using the navigation pane for displaying messages.
* @param aTextResourceId the resource ID of the message to display
*/
void CFilmReelContainer::SetNaviLabelTextL(TInt aTextResourceId)
{
    HBufC* text = StringLoader::LoadLC(aTextResourceId);
    SetNaviLabelTextL(*text);
    CleanupStack::PopAndDestroy(text); // text
}

/**
* Provides user feedback using the navigation pane for displaying messages.
* @param aText the text message to display
*/
void CFilmReelContainer::SetNaviLabelTextL(const TDesC& aText)
{
    if (iNaviLabel)
    {
        iNaviLabel->SetTextL(aText);
        iNaviPane->DrawNow();
    }
}

/**
* Called by the framework to draw this control.  Clears the area in
* aRect. Draws preview bitmap while previewing otherwise draws the
* created collage bitmap.
* @param aRect in which to draw
*/
void CFilmReelContainer::Draw(const TRect& aRect) const
{
    CWindowGc& gc = SystemGc();
    gc.Clear(aRect);

    switch(iContainerState)
    {
        case EPreviewing:
            gc.DrawBitmap(Rect(), iBitmap, iBitmap->SizeInPixels());
            break;
        case ERecording:
        case EDisplayingResult:
        case ESavingImage:
            gc.DrawBitmap(Rect(), iCollageBitmap, iCollageBitmap->SizeInPixels());
            break;
        case EPoweredDown:
            DisplayMessage(*iTimeOutText, gc);
            break;
        case ENotReady:
        default:
            DisplayMessage(*iNotReadyText, gc);
            break;
    }
}

/**
* Called by the framework to draw this control.  Clears the area in
* aRect. Draws preview bitmap while previewing otherwise draws the
* created collage bitmap.
* @param aMessage string to display
* @param aGc Window graphic context
*/
void CFilmReelContainer::DisplayMessage(const TDesC& aMessage, CWindowGc& aGc) const
{
    // Draw white background
    aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    aGc.SetBrushColor(KRgbWhite);
    aGc.DrawRect(Rect());

    // Draw black outline
    aGc.SetBrushStyle(CGraphicsContext::ENullBrush);
    aGc.SetBrushColor(KRgbBlack);
    aGc.DrawRect(Rect());

    aGc.SetPenColor(KRgbBlack);
    const CFont* fontUsed = iEikonEnv->TitleFont();
    aGc.UseFont(fontUsed);

    // Set text position on screen
    TInt baseline = Rect().Height() - fontUsed->AscentInPixels() * KFractionOfFontSizeToLowerText;
    // Margin is zero so that the text will be centred
    TInt margin = 0;

    aGc.DrawText(aMessage, Rect(), baseline, CGraphicsContext::ECenter, margin);
}

/**
* Called by the camera manager when the asyncronous request to
* take a picture completes. Depending on the current state either
* makes a request to take the next picture for previewing or adds
* the current picture to the collagebitmap, then asking for another
* picture to be taken or changing the state to display the collagebitmap
*/
void CFilmReelContainer::PictureTakenL()
{
    // picture has been taken, so display the bitmap
    DrawNow();

    switch(iContainerState)
    {
        case EPreviewing:
            // take next preview picture
            RequestPictureAfterPause();
            break;
        case ERecording:
        {
            // copy image onto the collage bitmap
            iBGc->BitBlt(TPoint(iX * KHorizontalDistance, iY * KVerticalDistance), iBitmap);

            iCount++;
            if (iCount == KTotalNumberOfPictures)
            {
                // When the collage bitmap is filled, reset the
                // iCount to 0, and set iX and iY back to the top-corner
                iCount = 0;
                iX = 0;
                iY = 0;

                iContainerState = ESavingImage; // set flag, can't take new pictures when saving
                SetNaviLabelTextL(R_SAVING_TEXT);
                SaveImageL(); // Save the image to file
            }
            else
            {
                iX++; // Increase the horizintal position of the next image
                if (iX == KNumberOfPicturesInRow)
                {
                    // If at the end of a row, move to the beginning of the next row.
                    iY++;
                    iX = 0;
                }
                // take next picture.
                RequestPictureAfterPause();
            }
        }
            break;
        case EDisplayingResult:
            // No need to do anything here, if we are displaying the created image
            break;
        default:
            break;
    };
}

/**
* Called by the camera manager when the asyncronous request to
* turn the camera on completes. Changes the state to previewing and
* asks camera manager for the first preview picture.
*/
void CFilmReelContainer::CameraReadyL()
{
    // start preview
    iContainerState = EPreviewing;
    SetNaviLabelTextL(R_PREVIEWING_TEXT);

    iCameraManager->TakePicture(*iBitmap);
}

/**
* Called by the camera manager when the has been an error
* in the camera manager.
* @param aError contains the error
*/
void CFilmReelContainer::CameraErrorL(TInt aError)
{
    if (aError == KErrBadPower)
    {
        iContainerState = EPoweredDown;
        SetNaviLabelTextL(R_TIMED_OUT_TEXT);
        DrawNow();
    }
}

/**
* Returns the current state of the container
* @return the current state of the FilmReelcontainer
*/
CFilmReelContainer::TContainerState CFilmReelContainer::CurrentState() const
{
    return iContainerState;
}

/**
* Changes the container back into previewing mode,
* updating the softkeys and starts the preview loop
*/
void CFilmReelContainer::PreviewModeL()
{
    if (iContainerState == EPoweredDown)
    {
        iCameraManager->StartCamera();
    }

    if (iContainerState == EDisplayingResult)
    {
        iContainerState = EPreviewing;
        SetNaviLabelTextL(R_PREVIEWING_TEXT);

        CEikButtonGroupContainer* cba = iAvkonAppUi->Cba();
        cba->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_EXIT);
        cba->DrawDeferred();

        // take next preview picture
        iBitmap->Reset();
        iCameraManager->TakePicture(*iBitmap);
        iCameraTimer->SetDelay(KDefaultDelay);
    }
}

/**
* Changes the container into recording mode, clearing the collagebitmap
* and slowing down the camera timer.
*/
void CFilmReelContainer::RecordModeL()
{
    if (iContainerState == EPreviewing)
    {
        iContainerState = ERecording; // switch to recording
        SetNaviLabelTextL(R_RECORDING_TEXT);

        // Clear  the collageBitmap to a white background
        iBGc->SetBrushColor(KRgbWhite);
        iBGc->Clear();

        // Slow down the timer for recording
        iCameraTimer->SetDelay(KFilmReelSpeed);
    }
}

/**
* Changes the container state to displaying and updates the softkeys
*/
void CFilmReelContainer::DisplayModeL()
{
    if (iContainerState == ESavingImage)
    {
        // Extract filename from full path
        iContainerState = EDisplayingResult;
        TParse parseToImageName;
        parseToImageName.Set(iFileName, NULL, NULL);
        iImageName = parseToImageName.Name();
        SetNaviLabelTextL(iImageName);

        CEikButtonGroupContainer* cba = iAvkonAppUi->Cba();
        cba->SetCommandSetL(R_FILMREEL_SOFTKEYS_OPTIONS_DELETE);
        cba->DrawDeferred();
    }
}

/**
* Returns a reference to the filename of the last image saved
*/
const TFileName& CFilmReelContainer::FileName() const
{
    return iFileName;
}

/**
* Returns a reference to the name of the last image saved
*/
const TFileName& CFilmReelContainer::ImageName() const
{
    return iImageName;
}

/**
* Saves the current collageBitmap to the photo album
*/
void CFilmReelContainer::SaveImageL()
{
    // Be sure that we have an image to be saved
    HBufC* imageroot = TPAlbSettings::RootImageFolderLC(); // gets the name of the photo album folder
    iFileName = *imageroot;
    iFileName.Append(KDefaultFileName);

    // generate filename using the framework's file server connection
    CEikApplication::GenerateFileName(iCoeEnv->FsSession(), iFileName);
    CleanupStack::PopAndDestroy(imageroot);

    // Create Format and Codec
    iFormat->iSettings.iQualityFactor = KJpgSavingQualityFactor; // quality factor from 0 to 100 (55 used here)
    iFormat->iSettings.iSampleScheme = TMdaJpgSettings::TColorSampling(TMdaJpgSettings::EColor420);

    // Create a file to save the image into
    // this is done in an asynch function
    iFileSaver->CreateL(iFileName, iFormat, NULL, NULL);
}

/**
* This function is called when the asynchronous function
* iFileSaver->CreateL() completes. Successfully or not. The error value tells if the
* creation was successful. If it was, we have created a file
* into which we can now save the image.
*
* @param aError the error value
*/
void CFilmReelContainer::MiuoCreateComplete(TInt aError)
{
    if ((aError == KErrNone) && iFileSaver)
    {
        // TRAP is used because this function cannot leave (no trailing L; name inherited from observer)
        // any error is ignored
        TRAPD( error, iFileSaver->ConvertL(*(iCollageBitmap), TRect(0, 0, 0, 0), 0));
    }
}

/**
* This function is called when the asynchronous function
* iFileSaver->ConvertL() completes. Now the image saving has
* completed.
*
* @param aError the error value
*/
void CFilmReelContainer::MiuoConvertComplete(TInt /*aError*/)
{
    // TRAP is used because this function cannot leave (no trailing L; name inherited from observer)
    // any error is ignored
    TRAPD(error,DisplayModeL());
}

/**
 * Observer method for the Media Server operations.
 * Gets called when the CMdaImageFileToBitmapUtility has opened
 * an image file. Not used here.
 *
 * @param aError error number, e.g. KErrNone if an error occured
 */
void CFilmReelContainer::MiuoOpenComplete(TInt /*aError*/)
{
}

/**
* Starts the camera timer
*/
void CFilmReelContainer::RequestPictureAfterPause()
{
    iCameraTimer->StartTimer();
}

/**
* Called by the camera timer, when the requested time has elasped
* makes a call to the cameramanager to take a picture
*/
void CFilmReelContainer::TimerCompleted()
{
    iBitmap->Reset();
    iCameraManager->TakePicture(*iBitmap);
}

// End of File

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?