src/screensaverindicatorarray.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 25 May 2010 12:43:23 +0300
branchRCL_3
changeset 18 2e08ef6b6eda
parent 0 040fcad49f44
permissions -rw-r--r--
Revision: 201019 Kit: 2010121

/*
* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:   CScreensaverIndicatorArray implementation.
*
*/



#include <barsread.h>
#include <screensaver.rsg>
#include <AknUtils.h>

#include "screensaverindicatorarray.h"
#include "screensaverindicatornumberandicon.h"
#include "screensaverindicatortext.h"
#include "screensaverindicatoricon.h"
#include "screensaverutility.h"

const TInt KInvertedColors = 1;


// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::NewL
// -----------------------------------------------------------------------------
//
CScreensaverIndicatorArray* CScreensaverIndicatorArray::NewL( TBool aColorInversionUsed )
    {
    CScreensaverIndicatorArray* array = new(ELeave) CScreensaverIndicatorArray();
    CleanupStack::PushL(array);
    array->ConstructL( aColorInversionUsed );
    CleanupStack::Pop(); // array

    return array;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::~CScreensaverIndicatorArray
// -----------------------------------------------------------------------------
//
CScreensaverIndicatorArray::~CScreensaverIndicatorArray()
    {
    if (iIndicators)
        {
        iIndicators->ResetAndDestroy();
        }
    delete iIndicators;
    delete iDependencyRecord;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::NewIndicatorLC
// -----------------------------------------------------------------------------
//
CScreensaverIndicator *CScreensaverIndicatorArray::NewIndicatorLC(
        TScreensaverIndicatorType aId)
    {
    CScreensaverIndicator *result= NULL;

    switch (aId)
        {
        case ESsIconIndicator:
            result = new( ELeave ) CScreensaverIndicatorIcon();
            break;
        case ESsTextIndicator:
            result = new( ELeave ) CScreensaverIndicatorText();
            break;
        case ESsNumberAndIconIndicator:
            result = new( ELeave ) CScreensaverIndicatorNumberAndIcon();
            break;
        default:
            User::Leave(KErrCorrupt);
        }

    CleanupStack::PushL( result );
    result->SetType(aId);

    return result;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::ConstructL
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::ConstructL( TBool aColorInversionUsed )
    {
    if (aColorInversionUsed == KInvertedColors)
        {
        iBgColor = TRgb(KRgbBlack).Value();
        iTextColor = TRgb(KRgbWhite).Value();
        }
    else //aColorInversionUsed == KNormalColors
        {
        iBgColor = TRgb(KRgbWhite).Value();
        iTextColor = TRgb(KRgbBlack).Value();
        }
    
    ConstructFromResourceL();

    }


// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::ConstructFromResourceL
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::ConstructFromResourceL()
    {
    ConstructParamFromResourceL();

    ConstructIndArrayL();
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::ConstructParamFromResourceL
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::ConstructParamFromResourceL()
    {
    TResourceReader reader;

    CEikonEnv::Static()->CreateResourceReaderLC( reader, R_SCREENSAVER_PARAMETERS );
    iMargin = reader.ReadInt16();
    iGap = reader.ReadInt16();
    iTopMargin = reader.ReadInt16();
    iTextLevel = reader.ReadInt16();
    iHeight = reader.ReadInt16();
    CleanupStack::PopAndDestroy(); // reader
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::ConstructIndArrayL
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::ConstructIndArrayL()
    {
    if( AknLayoutUtils::ScalableLayoutInterfaceAvailable() )
        {//use the new layout
        ConstructIndicatorsL( R_SCREENSAVER_INDICATOR_ARRAY_NEW_LAYOUT );
        }
    else
        {//use the old layout
        ConstructIndicatorsL( R_SCREENSAVER_INDICATOR_ARRAY );
        }
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::ConstructIndicatorsL
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::ConstructIndicatorsL( TInt aResourceId )
    {
    TResourceReader reader;

    CEikonEnv::Static()->CreateResourceReaderLC(
        reader, aResourceId);
    
    iCount = reader.ReadInt16();

    iIndicators = new( ELeave ) CArrayPtrFlat<CScreensaverIndicator>( iCount );
    iDependencyRecord = new( ELeave ) CArrayFixFlat<TBool>( iCount );

    CScreensaverIndicator *nInd;
    TInt32 type;
    for (TInt i = 0; i < iCount; i++)
        {
        iDependencyRecord->AppendL( ETrue );
        type = reader.ReadInt32();
        nInd = NewIndicatorLC( ( TScreensaverIndicatorType ) type );
        nInd->ConstructL( reader, iBgColor, iTextColor );
        iIndicators->InsertL( 0, nInd );
        CleanupStack::Pop(); // nInd
        }

    CleanupStack::PopAndDestroy(); // reader
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::Dependency
// -----------------------------------------------------------------------------
//
TBool CScreensaverIndicatorArray::Dependency(TInt aIndex) const
    {
    return (*iDependencyRecord)[aIndex];
    }
// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::Setup
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::Setup( TAknLayoutRect& aLayoutRect,
        TAknLayoutText& aLayoutText, TAknLayoutRect& aLayoutInds )
    {
    // Reset drawing parameters (do not use those defined in resources)
    iRect = aLayoutRect.Rect();

    TInt rightMargin = 0;
    // Left margin = indicators left edge - indicator area left edge
    // Right margin = 0, the AM/PM indicator needs to be on the edge
    // Except when mirrored the other way around. Right margin can be reduced
    // by 1 when mirrored, because the icons contain a border on top & right 
    if ( AknLayoutUtils::LayoutMirrored() )
        {
        iMargin = 0;
        rightMargin = aLayoutInds.Rect().iTl.iX - iRect.iTl.iX - 1;
        }
    else
        {
        iMargin = aLayoutInds.Rect().iTl.iX - iRect.iTl.iX;
        rightMargin = 0;
        }

    TInt currentX = iRect.iBr.iX - rightMargin;

    TInt leftmostRightAlignedBorder = iRect.iBr.iX - rightMargin; // iMargin;

    // This is done in two passes, first we set up right-aligned indicators
    // and then left-aligned. If any left-aligned indicator overlaps with leftmost
    // right-aligned indicator the the process is stopped (right-aligned
    // indicators have higher priority).
    for ( TInt i = 0; i < iIndicators->Count(); i++ )
        {
        if (iIndicators->At(i)->Alignment() != ESsAlignRight)
            {
            continue;
            }
        
        SetIndicatorsAttribute( i, aLayoutText, aLayoutInds, currentX );

        if (iIndicators->At(i)->Visible())
            {
            currentX -= iIndicators->At(i)->Width() + iGap;
            leftmostRightAlignedBorder = currentX;
            if (currentX < iMargin)
                {
                break;
                }
            }
        }

    // Start second round from left edge
    currentX = iRect.iTl.iX + iMargin;
    for ( TInt i = 0; i < iIndicators->Count(); i++ )
        {
        if (iIndicators->At(i)->Alignment() != ESsAlignLeft)
            {
            continue;
            }
        
        SetIndicatorsAttribute( i, aLayoutText, aLayoutInds, currentX );

        if (iIndicators->At(i)->Visible())
            {
            if (currentX + iIndicators->At(i)->Width() + iGap >= leftmostRightAlignedBorder)
                {
                iIndicators->At(i)->SetVisibility(EFalse);
                break;
                }
            currentX += iIndicators->At(i)->Width() + iGap;
            if (currentX > iRect.Width() - iMargin)
                {
                break;
                }
            }
        }
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::SetIndicatorsAttribute
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::SetIndicatorsAttribute( 
        TInt& Ind,
        TAknLayoutText& aLayoutText,
        TAknLayoutRect& aLayoutInds,
        TInt& aCurrentX )
    {

    // Set text layout for text containing indicators
    iIndicators->At(Ind)->SetTextLayout(aLayoutText, aCurrentX);

    // Set icon layout for icon containing indicators
    iIndicators->At(Ind)->SetIconLayout(aLayoutInds, aCurrentX);

    // Not visible, if conditions (e.g. there's icon & payload) are not met,
    // or there's no reason to show the indicator
    if (!iIndicators->At(Ind)->CheckVisibilityConditions() || Dependency(iIndicators->At(Ind)->Id()))
        {
        iIndicators->At(Ind)->SetVisibility(EFalse);        
        }
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::Draw
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::Draw(CWindowGc& aGc) const
    {
    aGc.SetBrushColor(iBgColor);
    aGc.SetPenColor(iTextColor);
    aGc.Clear(iRect);

    for (TInt i = 0; i < iIndicators->Count(); i++)
        {
        if (iIndicators->At(i)->Visible())
            {
            iIndicators->At(i)->Draw(aGc);
            }
        }
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::CheckDependencyConflict
// -----------------------------------------------------------------------------
//
TBool CScreensaverIndicatorArray::CheckDependencyConflict(
        TScreensaverIndicatorId aId) const
    {
    if ((iDependencyRecord) && (aId < iCount))
        {
        return Dependency(aId);
        }

    return EFalse;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::SetDependencyStatus
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::SetDependencyStatus(
        TScreensaverIndicatorId aId, TBool aValue)
    {
    if ((iDependencyRecord) && (aId < iCount))
        {
        (*iDependencyRecord)[aId] = aValue;
        }
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::GetIndicatorPayload
// -----------------------------------------------------------------------------
//
TInt CScreensaverIndicatorArray::GetIndicatorPayload(
        TScreensaverIndicatorId aId, TIndicatorPayload& aPayload) const
    {
    if (aId < iCount)
        {
        for (TInt i = 0; i < iIndicators->Count(); i++)
            {
            if (aId == iIndicators->At(i)->Id())
                {
                iIndicators->At(i)->Payload(aPayload);
                return KErrNone;
                }
            }
        }

    return KErrCorrupt;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::SetIndicatorPayload
// -----------------------------------------------------------------------------
//
TInt CScreensaverIndicatorArray::SetIndicatorPayload(
        TScreensaverIndicatorId aId, const TIndicatorPayload& aPayload)
    {
    if (aId < iCount)
        {
        for (TInt i = 0; i < iIndicators->Count(); i++)
            {
            if (aId == iIndicators->At(i)->Id())
                {
                iIndicators->At(i)->SetPayload(aPayload);
                return KErrNone;
                }
            }
        }

    return KErrCorrupt;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::PreferredDrawingMode
// -----------------------------------------------------------------------------
//
TScreensaverDrawType CScreensaverIndicatorArray::PreferredDrawingMode() const
    {
    TScreensaverDrawType result = ESsDrawTypeNotDrawn; // Default mode.

    for (TInt i = 0; i < iIndicators->Count(); i++)
        {
        if ((iIndicators->At(i)->CheckVisibilityConditions() == EFalse)
                || (CheckDependencyConflict(iIndicators->At(i)->Id())))
            {
            // This indicator can't be visible or there is 
            // dependency conflict -> continue.
            continue;
            }

        switch (iIndicators->At(i)->DrawType())
            {
            case ESsDrawTypePrimary:
                // Primary draw type overides everything,
                // so we can return immediately. 
                return ESsDrawTypePrimary;
            case ESsDrawTypeSecondary:
                result = ESsDrawTypeSecondary;
                break;
            default:
                break;
            }
        }

    return result;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::ActualDrawingMode
// -----------------------------------------------------------------------------
//
TScreensaverDrawType CScreensaverIndicatorArray::ActualDrawingMode() const
    {
    TScreensaverDrawType result = ESsDrawTypeNotDrawn; // Default mode.
    
    for (TInt i = 0; i < iIndicators->Count(); i++)
        {
        if ((iIndicators->At(i)->CheckVisibilityConditions() == EFalse)
                || !( iIndicators->At(i)->Visible() ) )
            {
            // This indicator can't be visible or it is visible
            continue;
            }
        
        switch (iIndicators->At(i)->DrawType())
            {
            case ESsDrawTypePrimary:
                return ESsDrawTypePrimary; // Primary draw type overides everything.
            case ESsDrawTypeSecondary:
                result = ESsDrawTypeSecondary;
                break;
            default:
                break;
            }
        }

    return result;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::Height
// -----------------------------------------------------------------------------
//
TInt CScreensaverIndicatorArray::Height() const
    {
    return iHeight;
    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::SetVisibilityForIndicators
// -----------------------------------------------------------------------------
//
void CScreensaverIndicatorArray::SetVisibilityForIndicators()
    {
    for (int i = 0; i < iIndicators->Count(); i++)
        {
        // Not visible, if conditions (e.g. there's icon & payload) are not met,
        // or there's no reason to show the indicator
        if (!iIndicators->At(i)->CheckVisibilityConditions() || Dependency(iIndicators->At(i)->Id()))
            {
            iIndicators->At(i)->SetVisibility(EFalse);
            }
        else
            iIndicators->At(i)->SetVisibility(ETrue);
        }

    }

// -----------------------------------------------------------------------------
// CScreensaverIndicatorArray::CScreensaverIndicatorArray
// -----------------------------------------------------------------------------
//
CScreensaverIndicatorArray::CScreensaverIndicatorArray()
    {
    
    }

// End of files