diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/AknTransitionUtils/src/akntransitionutils.cpp --- /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 +#include +#include +#include +#include + +#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( 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 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( 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( 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 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 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 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( 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(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; + } + } + } +