uifw/AvKon/AknTransitionUtils/src/akntransitionutils.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/AknTransitionUtils/src/akntransitionutils.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,687 @@
+/*
+* Copyright (c) 2007 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:  Transition utilities.
+*
+*/
+
+
+#include <coecntrl.h>
+#include <avkondomainpskeys.h>
+#include <centralrepository.h>
+#include <pslninternalcrkeys.h>
+#include <AknUtils.h>
+
+#include "akntransitionutils.h"
+#include "aknpsobserver.h"
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+struct CAknTransitionUtils::TDataEntry
+    {
+    TDataEntry( const TInt iKey, TAny* aData );
+      
+    static TBool SameKey( const TDataEntry& aEntry1,
+                          const TDataEntry& aEntry2 );
+
+    const TInt iKey;
+    TAny* iData;
+    };
+        
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+struct CAknTransitionUtils::TTransitionObserver
+    {
+    TTransitionObserver( const TInt iKey, TInt iEvents,
+                         MAknTransitionUtilsObserver* aObserver );
+ 
+    static TBool Equal( const TTransitionObserver& aObserver1,
+                        const TTransitionObserver& aObserver2 );
+
+    TInt iEvents;        
+    TInt iKey;
+    MAknTransitionUtilsObserver* iObserver;
+    };
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CAknTransitionUtils::TDataEntry::TDataEntry( const TInt aKey, 
+                                             TAny* aData ) :
+        iKey( aKey ), iData( aData )
+    {
+    }
+        
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CAknTransitionUtils::TDataEntry::SameKey( const TDataEntry& aEntry1, 
+                                                const TDataEntry& aEntry2 )
+    {
+    return aEntry1.iKey == aEntry2.iKey;
+    }
+    
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CAknTransitionUtils::TTransitionObserver::TTransitionObserver( 
+            const TInt aKey, const TInt aEvents, 
+            MAknTransitionUtilsObserver* aObserver ) :
+    iEvents( ( TEvents )aEvents ), iKey( aKey ), iObserver( aObserver )
+    {
+    }
+ 
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CAknTransitionUtils::TTransitionObserver::Equal( 
+        const TTransitionObserver& aObserver1,
+        const TTransitionObserver& aObserver2 )
+    {
+    return aObserver1.iObserver == aObserver2.iObserver;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CAknTransitionUtils::~CAknTransitionUtils() 
+    {
+    TInt count = iUserData.Count();        
+    for ( TInt i = 0; i < count; i++ )
+        {
+        delete iUserData[i];
+        }
+            
+    count = iObservers.Count();        
+    for ( TInt i = 0; i < count; i++ )
+        {
+        delete iObservers[i];
+        }
+
+    iUserData.Reset();
+    iObservers.Reset();
+    delete iPsObserver;
+    delete iRepository;
+    };
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknTransitionUtils::AddObserver( 
+        MAknTransitionUtilsObserver* aObserver, TInt aEvents,  
+        const TDesC8* aParams )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return KErrNoMemory;
+        }
+    
+    TInt key = reinterpret_cast<TInt>( aParams );
+    TInt count = singleton->iObservers.Count();
+    TInt newEvents = 0;
+    TBool foundObserver = EFalse;
+    for ( TInt i = 0; i < count; i++ )
+        {
+        TTransitionObserver* o = singleton->iObservers[i];
+        if ( o->iObserver == aObserver )
+            {
+            foundObserver = ETrue;
+            newEvents = aEvents & ~o->iEvents;
+            o->iEvents |= aEvents;
+            break;
+            }
+        }
+        
+    if ( !foundObserver )
+        {
+        TTransitionObserver* o = new TTransitionObserver( key, aEvents, 
+                                                          aObserver );
+        if ( !o )
+            {
+            return KErrNoMemory;
+            }
+        singleton->iObservers.Append( o );
+        newEvents = aEvents;
+        }
+
+    if ( newEvents & EEventControlTransitionFinished )
+        {
+        GfxTransEffect::SetTransitionObserver( singleton );
+        singleton->iNumControlTransitionObservers++;
+        }
+    
+    if ( newEvents & EEventWsBufferRedirection )
+        {
+        if ( !singleton->iPsObserver )
+            {
+            singleton->iPsObserver = CAknPsObserver::New( singleton, 
+                                                          KPSUidAvkonDomain, 
+                                                          KAknTfxServerRedirectionStatus );
+            if ( !singleton->iPsObserver )
+                {
+                return KErrNoMemory;
+                }
+             TInt value = 0;
+             singleton->iPsObserver->GetCurrentValue( value ); 
+             singleton->iScreenRedirected = value & ETfxScreenRedirected;
+            }
+        singleton->iNumPsObservers++;
+        }
+        
+    return KErrNone;
+    }
+  
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknTransitionUtils::RemoveObserver( 
+        MAknTransitionUtilsObserver* aObserver, TInt aEvents )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return KErrNoMemory;
+        }
+
+    TIdentityRelation<TTransitionObserver> identity( 
+                                              TTransitionObserver::Equal );
+    TTransitionObserver tmp( 0, aEvents, aObserver );
+    TInt index = singleton->iObservers.Find( &tmp, identity );
+    if ( index != KErrNotFound )
+        {
+        TTransitionObserver* o = singleton->iObservers[index];
+        TInt removedEvents = aEvents & o->iEvents;
+        o->iEvents &= ~removedEvents;
+
+        if ( o->iEvents == 0 )
+            {
+            delete singleton->iObservers[index];
+            singleton->iObservers.Remove( index );
+            }
+            
+        if ( removedEvents & EEventControlTransitionFinished )
+            {
+            if ( --singleton->iNumControlTransitionObservers == 0 )
+                {
+                GfxTransEffect::SetTransitionObserver( NULL );
+                }
+            }
+        
+        if ( removedEvents & EEventWsBufferRedirection )
+            {
+            if ( --singleton->iNumPsObservers == 0 )
+                {
+                delete singleton->iPsObserver;
+                singleton->iPsObserver = NULL;
+                }
+            }
+        
+        return KErrNone;
+        }
+        
+    return KErrNotFound;
+    }
+    
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknTransitionUtils::GetState( TInt aEvent, TInt* aState, 
+                                             TDes8* /*aParams*/ )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return KErrNoMemory;
+        }
+        
+    if ( aEvent & EEventWsBufferRedirection )
+        {
+        *aState = singleton->iScreenRedirected;
+        }
+    else
+        {
+        return KErrNotSupported;
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CAknTransitionUtils::TransitionFinished( const CCoeControl* aControl, 
+                                              TUint /* aAction */ )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return;
+        }
+
+    TInt key = reinterpret_cast<TInt>( aControl );
+
+    for ( TInt i = 0; i < singleton->iObservers.Count(); i++ )
+        {
+        if ( ( singleton->iObservers[i]->iEvents & 
+               EEventControlTransitionFinished ) &&
+             ( singleton->iObservers[i]->iKey == key ) )
+            {
+            singleton->iObservers[i]->iObserver->AknTransitionCallback(
+                EEventControlTransitionFinished, 0, 
+                reinterpret_cast<const TDesC8*>( aControl ) );
+            }
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CAknTransitionUtils::PsValueUpdated( const TUid /* aCategory */, 
+                                          const TUint /* aKey */,
+                                          const TInt aVal )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return;
+        }
+
+    iScreenRedirected = aVal & ETfxScreenRedirected;
+
+    for ( TInt i = 0; i < singleton->iObservers.Count(); i++ )
+        {
+        if ( singleton->iObservers[i]->iEvents & EEventWsBufferRedirection )
+            {
+           	MAknTransitionUtilsObserver* observer = singleton->iObservers[i]->iObserver;
+           	observer->AknTransitionCallback(
+                EEventWsBufferRedirection, iScreenRedirected );
+            if ( (i >= singleton->iObservers.Count() ) // Out of bounds
+            	|| ( observer != singleton->iObservers[i]->iObserver ) ) // removed
+            	{
+            	// Observer removed itself during AknTransitionCallback()
+            	i--;
+            	}
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknTransitionUtils::RemoveData( const TInt aKey )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return;
+        }
+
+    TIdentityRelation<TDataEntry> identity( TDataEntry::SameKey );
+    TDataEntry tmp( aKey, NULL );
+    TInt index = singleton->iUserData.Find( &tmp, identity );
+    if ( index != KErrNotFound )
+        {
+        delete singleton->iUserData[index];
+        singleton->iUserData.Remove( index );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknTransitionUtils::SetData( const TInt aKey, TAny* aData )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return KErrNoMemory;
+        }
+        
+    TIdentityRelation<TDataEntry> identity( TDataEntry::SameKey );
+    TDataEntry* tmp = new TDataEntry( aKey, aData );
+    if ( !tmp )
+        {
+        return KErrNoMemory;
+        }
+    TInt index = singleton->iUserData.Find( tmp, identity );
+    if ( index != KErrNotFound )
+        {
+        delete singleton->iUserData[index];
+        singleton->iUserData.Remove( index );
+        }
+
+    singleton->iUserData.Append( tmp );
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TAny* CAknTransitionUtils::GetData( const TInt aKey )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return NULL;
+        }
+        
+    TIdentityRelation<TDataEntry> identity( TDataEntry::SameKey );
+    TDataEntry tmp( aKey, NULL );
+    TInt index = singleton->iUserData.Find( &tmp, identity );
+    if ( index != KErrNotFound )
+        {
+        return singleton->iUserData[index]->iData;
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+        
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknTransitionUtils::SetAllParents( const CCoeControl* aControl )
+    {
+    CCoeControl* child = NULL;
+    CCoeControl* parent = const_cast<CCoeControl*>( aControl );
+
+    TInt compControlCount = parent->CountComponentControls();
+
+    for( TInt i( 0 ); i < compControlCount; i++ )
+        {
+        child = parent->ComponentControl( i );
+        if ( child )
+            {
+            child->SetParent( parent );
+            SetAllParents( child );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknTransitionUtils::TransitionsEnabled( TInt aEffectCategory )
+    {
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        // if singleton does not exist we create a temporary CRepository
+        // to check the value
+        CRepository* rep( NULL ); 
+        TRAPD( err, rep = CRepository::NewL( KCRUidThemes ) );
+        if ( err != KErrNone )
+            {
+            delete rep;
+            return EFalse;
+            }       
+        TInt val;
+        err = rep->Get( KThemesTransitionEffects, val );
+        if ( err != KErrNone )
+            {
+            delete rep;
+            return EFalse;
+            }
+ 
+        if ( val & aEffectCategory )
+            {
+            delete rep;
+            return EFalse;
+            }
+    
+        delete rep;
+        return ETrue;
+        }
+
+    if ( !singleton->iRepository )
+        {
+        TRAPD( err, singleton->iRepository = CRepository::NewL( KCRUidThemes ) );
+        if ( err != KErrNone )
+            {
+            return EFalse;
+            }
+        }
+
+    TInt val;
+    TInt err = singleton->iRepository->Get( KThemesTransitionEffects, val );
+    if ( err != KErrNone )
+        {
+        return EFalse;
+        }
+
+    if ( val & aEffectCategory )
+        {
+        return EFalse;
+        }
+    
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TInt CAknTransitionUtils::MakeVisibleSubComponentsR( CCoeControl* aControl,
+                                        TMakeVisibleSubComponentsInfo aInfo )
+    {
+    CCoeControl* child = NULL;
+    TInt compControlCount = aControl->CountComponentControls();
+
+    for( TInt i = 0; i < compControlCount; i++ )
+        {
+        child = aControl->ComponentControl( i );
+        if( child )
+            {
+            if( child->OwnsWindow() )
+                {
+                TBool makeVisible;
+                TBool call = ETrue;
+                TBool visible = child->IsVisible();
+                switch ( aInfo )
+                    {
+                    case EForceInvisible:
+                    case EDisappearInvisible:
+                        makeVisible = EFalse;
+                        break;
+                    case EForceVisible:
+                        makeVisible = ETrue;
+                        break;
+                    case EAppearInvisible:
+                        call = visible;
+                        if ( !visible &&
+                             iIgnoredChildControls.Append( child ) == KErrNone )
+                            {
+                            GfxTransEffect::NotifyExternalState(
+                                                    EAddIgnoreWOChildComponent,
+                                                    ( const TDesC8* ) child );
+                            }
+                        makeVisible = EFalse;
+                        break;
+                    case EAppearVisible:
+                        {
+                        TInt pos = iIgnoredChildControls.Find( child );
+                        if ( pos >= 0 )
+                            {
+                            iIgnoredChildControls.Remove( pos );
+                            GfxTransEffect::NotifyExternalState(
+                                                ERemoveIgnoreWOChildComponent,
+                                                ( const TDesC8* ) child );
+                            call = EFalse;
+                            }
+                        makeVisible = ETrue;
+                        }
+                        break;
+                    default:
+                        call = ETrue;
+                        makeVisible = ETrue;
+                    }
+                if ( call )
+                    {
+                    child->MakeVisible( makeVisible );
+                    }
+                }
+            MakeVisibleSubComponentsR( child, aInfo );
+            }
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknTransitionUtils::MakeVisibleSubComponents(
+        CCoeControl* aControl, TMakeVisibleSubComponentsInfo aInfo )
+    {
+    TInt err = KErrNone;
+    CAknTransitionUtils* singleton = CAknTransitionUtils::Static();
+    if ( !singleton )
+        {
+        return KErrNoMemory;
+        }
+
+    if ( aInfo != EClearIgnored )
+        {
+        err = singleton->MakeVisibleSubComponentsR( aControl, aInfo );
+        }
+
+    if ( aInfo == EClearIgnored || aInfo == EAppearVisible )
+        {
+        for ( TInt i = 0; i < singleton->iIgnoredChildControls.Count(); i++ )
+            {
+            GfxTransEffect::NotifyExternalState( ERemoveIgnoreWOChildComponent,
+                        ( const TDesC8* ) singleton->iIgnoredChildControls[i] );
+            }
+        singleton->iIgnoredChildControls.Reset();
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+static void GetDemarcationOptionsMenu( TRect& aRect )
+    {
+    if ( AknLayoutUtils::LayoutMetricsRect( 
+            AknLayoutUtils::EControlPaneBottom, aRect ) )
+        {
+        // Options soft button on the left or right
+        return;
+        }
+    else
+        {
+        // Soft buttons at the bottom of the screen
+        AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EControlPane, aRect );
+        }
+    }
+    
+static void GetDemarcationPopup( TRect& aRect )
+    {
+    TRect controlTop;
+    TRect controlBottom;
+    TBool topRet = AknLayoutUtils::LayoutMetricsRect(
+        AknLayoutUtils::EControlPaneTop, controlTop);
+    TBool bottomRet = AknLayoutUtils::LayoutMetricsRect(
+        AknLayoutUtils::EControlPaneBottom, controlBottom);
+    if (bottomRet)
+        {
+        if (controlTop.iTl.iX == 0)
+            {
+            // The softkeys are on the left
+            aRect.iTl.iX = aRect.iBr.iX = 0;
+            aRect.iTl.iY = controlTop.iBr.iY;
+            aRect.iBr.iY = controlBottom.iTl.iY;
+            }
+        else
+            {
+            // The softkeys are on the right
+            aRect.iTl = controlTop.iBr;
+            aRect.iBr.iX = controlBottom.iBr.iX;
+            aRect.iBr.iY = controlBottom.iTl.iY;    
+            }
+        }
+    else
+        {
+        // The softkeys are on the top or bottom
+        AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, aRect);
+        }
+    }
+    
+EXPORT_C TInt CAknTransitionUtils::GetDemarcation( 
+        TGfxControlType aControlType, TRect& aRect )
+    {
+    if ( aControlType == EOptionsMenu )
+        {
+        GetDemarcationOptionsMenu( aRect );
+        }
+    else // EPopup
+        {
+        GetDemarcationPopup( aRect );
+        }
+
+    return KErrNone;
+    };
+    
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CAknTransitionUtils::CAknTransitionUtils() :
+        CCoeStatic( KAknTransitionUtilsUid, -1, CCoeStatic::EThread ),
+        iNumControlTransitionObservers( 0 )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CAknTransitionUtils* CAknTransitionUtils::Static()
+    {
+	CCoeEnv *env = CCoeEnv::Static();
+	if(!env)
+	{
+		return NULL;
+	}
+    CAknTransitionUtils* singleton = 
+        reinterpret_cast<CAknTransitionUtils*>(CCoeEnv::Static( 
+                                                  KAknTransitionUtilsUid ) );
+    if ( !singleton )
+        {
+        singleton = new CAknTransitionUtils();
+        }
+        
+    return singleton;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CAknTransitionUtils::RemoveControlTransitionObserver( const TInt aKey )
+    {
+    TInt count = iObservers.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        TTransitionObserver* o = iObservers[i];
+        if ( o->iKey == aKey )
+            {
+            CAknTransitionUtils::RemoveObserver( o->iObserver, 0xffffffff );
+            break;
+            }
+        }
+    }
+