src/screensaverindicatorarray.cpp
branchRCL_3
changeset 26 e8d784ac1a4b
parent 0 040fcad49f44
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/screensaverindicatorarray.cpp	Wed Sep 01 12:30:40 2010 +0100
@@ -0,0 +1,498 @@
+/*
+* 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