--- /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;
+ }
+ }
+ }
+