diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/AknViewAppUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/AknViewAppUi.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,1211 @@ +/* +* Copyright (c) 2002-2005 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: +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aknview.h" +#include "aknshut.h" +#include "aknenv.h" +#include "AknPanic.h" +#ifdef RD_SPLIT_VIEW +#include "AknViewNavigator.h" +#include +#include +#include +#include +#endif // RD_SPLIT_VIEW +#include "aknViewAppUi.h" + +// CONSTANTS +const TInt KAknAppUiViewsGranularity = 1; +const TInt KAknViewAsyncPriority = EActivePriorityRedrawEvents + 10; +#ifdef RD_SPLIT_VIEW +const TInt KAknSplitViewSize = 2; + +// MODULE DATA STRUCTURES +enum TAknViewAppUiFlags + { + EAknViewAppUiButton1DownInRight = 0x00000001, + EAknViewAppUiButton1DownInLeft = 0x00000002, + EAknViewAppUiFromSplitToSingle = 0x00000004, + EAknViewAppUiFromSingleToSplit = 0x00000008, + }; +#endif // RD_SPLIT_VIEW + +/** +* CAknViewAppUi extension class. +* +* @lib avkon.lib +*/ +NONSHARABLE_CLASS(CAknViewAppUiExtension) : public CBase + { + public: + /** + * Two-phased constructor. + */ + static CAknViewAppUiExtension* NewL(); + + /** + * Destructor. + */ + ~CAknViewAppUiExtension(); + + private: + /** + * C++ constructor. + */ + CAknViewAppUiExtension(); + + /** + * Symbian 2nd-stage constructor. + */ + void ConstructL(); + + public: + RPointerArray iActiveViews; +#ifdef RD_SPLIT_VIEW + RArray iSplitViews; + CAknViewNavigator* iNavigator; + TInt iFlags; +#endif // RD_SPLIT_VIEW + TBool iUseDefaultScreenClearer; + }; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CAknViewAppUiExtension::CAknViewAppUiExtension +// C++ constructor. +// ----------------------------------------------------------------------------- +// +CAknViewAppUiExtension::CAknViewAppUiExtension() + { + iUseDefaultScreenClearer = ETrue; // by default clear the screen automatically + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUiExtension::~CAknViewAppUiExtension +// Destructor. +// ----------------------------------------------------------------------------- +// +CAknViewAppUiExtension::~CAknViewAppUiExtension() + { + iActiveViews.Close(); +#ifdef RD_SPLIT_VIEW + delete iNavigator; + iSplitViews.Close(); +#endif // RD_SPLIT_VIEW + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUiExtension::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CAknViewAppUiExtension* CAknViewAppUiExtension::NewL() + { + CAknViewAppUiExtension* ext = new ( ELeave ) CAknViewAppUiExtension; + CleanupStack::PushL( ext ); + ext->ConstructL(); + CleanupStack::Pop(); + return ext; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUiExtension::NewL +// Symbian 2nd-stage constructor. +// ----------------------------------------------------------------------------- +// +void CAknViewAppUiExtension::ConstructL() + { + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::TAknSplitViewContainer::IsPartOf +// Tests if a given view is part of the split view. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +TBool CAknViewAppUi::TAknSplitViewContainer::IsPartOf( const TUid aViewId ) + { + if ( aViewId == iViewIds[0] || aViewId == iViewIds[1] ) + { + return ETrue; + } + + return EFalse; + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::CViewActivationItem::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CAknViewAppUi::CViewActivationItem* CAknViewAppUi::CViewActivationItem::NewLC( CAknView* aNewView, TUid aCustomMessageId, const TDesC8& aCustomMessage, const TVwsViewId& aPrevViewId ) + { + CViewActivationItem* self = new ( ELeave ) CViewActivationItem( aNewView, aCustomMessageId, aPrevViewId ); + CleanupStack::PushL( self ); + self->ConstructL( aCustomMessage ); + return self; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::CViewActivationItem::~CViewActivationItem +// Destructor. +// ----------------------------------------------------------------------------- +// +CAknViewAppUi::CViewActivationItem::~CViewActivationItem() + { + delete iCustomMessage; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::CViewActivationItem::CViewActivationItem +// C++ default constructor. +// ----------------------------------------------------------------------------- +// +CAknViewAppUi::CViewActivationItem::CViewActivationItem( CAknView* aNewView, TUid aCustomMessageId, const TVwsViewId& aPrevViewId ) +: iNewView( aNewView ), iCustomMessageId( aCustomMessageId ), iPrevViewId( aPrevViewId ) + { + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::CViewActivationItem::ConstructL +// Symbian 2nd phase constructor. +// ----------------------------------------------------------------------------- +// +void CAknViewAppUi::CViewActivationItem::ConstructL( const TDesC8& aCustomMessage ) + { + iCustomMessage = aCustomMessage.AllocL(); + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::BaseConstructL +// Second-phase base class constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::BaseConstructL( TInt aAppUiFlags ) + { + CAknAppUi::BaseConstructL( aAppUiFlags ); + + iViews = new ( ELeave ) CAknViews( KAknAppUiViewsGranularity ); + iActivationQueue = new ( ELeave ) CAknViewActivationQueue( KAknAppUiViewsGranularity ); + iActivationTick = CIdle::NewL( KAknViewAsyncPriority ); + iShutter = CAknViewShutter::NewL( *iEikonEnv, this ); + + // Might be already constructed + if ( !iExtension ) + { + iExtension = CAknViewAppUiExtension::NewL(); + } + +#ifdef RD_SPLIT_VIEW + iExtension->iNavigator = new ( ELeave ) CAknViewNavigator( this ); + AddToStackL( iExtension->iNavigator, ECoeStackPriorityDefault - 1, ECoeStackFlagRefusesFocus ); +#endif // RD_SPLIT_VIEW + + if ( iEikonEnv->RootWin().OrdinalPosition() == 0 && // only clear the window for foreground apps + iExtension->iUseDefaultScreenClearer ) + { + iClearer = CAknLocalScreenClearer::NewL( ETrue ); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::~CAknViewAppUi +// Destructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CAknViewAppUi::~CAknViewAppUi() + { +#ifdef RD_SPLIT_VIEW + if (iExtension && iExtension->iNavigator ) + RemoveFromStack( iExtension->iNavigator ); +#endif // RD_SPLIT_VIEW + + // Hide application toolbar to prevent it from showing + // after views are deleted + if ( CAknAppUi::CurrentFixedToolbar() ) + { + CAknAppUi::CurrentFixedToolbar()->SetToolbarVisibility( EFalse ); + } + + delete iClearer; + delete iShutter; + delete iActivationTick; + + if ( iActivationQueue ) + { + iActivationQueue->ResetAndDestroy(); + delete iActivationQueue; + } + + if (iExtension) + for ( TInt i = 0; i < iExtension->iActiveViews.Count(); i++ ) + { + iExtension->iActiveViews[i]->AknViewDeactivated(); + } + + if ( iViews ) + { + TInt count( iViews->Count() ); + + for ( TInt i = 0; i < count; i++ ) + { + CCoeAppUi::DeregisterView( *iViews->At( i ) ); + } + + iViews->ResetAndDestroy(); + } + + delete iViews; + delete iExtension; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::AddViewL +// Registers a new view to the view server. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::AddViewL( CAknView* aView ) + { + // this is here to assert that BaseConstructL has been called properly. + Extension(); + + CCoeAppUi::RegisterViewL( *aView ); + iViews->AppendL( aView ); + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::RemoveView +// Deregisters a new view from the view server. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::RemoveView( TUid aViewId ) + { + const TInt count( iViews->Count() ); + + for ( TInt i = 0; i < count; ++i ) + { + CAknView* view( iViews->At( i ) ); + + if ( view->Id() == aViewId ) + { + iViews->Delete( i ); + CCoeAppUi::DeregisterView( *view ); + delete view; + return; + } + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::View +// Returns a view that has the given UID. +// ----------------------------------------------------------------------------- +// +EXPORT_C CAknView* CAknViewAppUi::View( TUid aView ) const + { + if ( iViews ) + { + const TInt count( iViews->Count() ); + + for ( TInt i = 0; i < count; ++i ) + { + CAknView* view( iViews->At( i ) ); + + if ( view->Id() == aView ) + { + return view; + } + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ProcessCommandL +// Processes a command. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::ProcessCommandL( TInt aCommand ) + { + MEikAppUiFactory* appUiFactory( iEikonEnv->AppUiFactory() ); + ASSERT( appUiFactory ); + + if ( appUiFactory->Popup() ) + { + ClosePopup(); + } + else if ( iView && iView->MenuBar() ) + { + iView->MenuBar()->StopDisplayingMenuBar(); + } + else if ( appUiFactory->MenuBar() ) + { + StopDisplayingMenuBar(); + } + + if ( aCommand == EAknSoftkeyOptions ) + { + if ( iView && iView->MenuBar() ) + { + iView->MenuBar()->TryDisplayMenuBarL(); + } + else if ( appUiFactory->MenuBar() ) + { + appUiFactory->MenuBar()->TryDisplayMenuBarL(); + } + + return; + } + if ( aCommand == EAknSoftkeyContextOptions ) + { + if ( iView && iView->MenuBar() ) + { + iView->MenuBar()->TryDisplayContextMenuBarL(); + } + else if ( appUiFactory->MenuBar() ) + { + appUiFactory->MenuBar()->TryDisplayContextMenuBarL(); + } + + return; + } + + if ( aCommand == EAknCmdExit ) + { + CAknEnv::RunAppShutter(); + return; + } + + if ( iView ) + { + iView->ProcessCommandL( aCommand ); + } + + if ( aCommand != EEikCmdCanceled ) + { + HandleCommandL( aCommand ); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ActivateLocalViewL +// Activates a local view. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::ActivateLocalViewL( TUid aViewId ) + { +#ifdef RD_SPLIT_VIEW + ActivateLocalViewL( aViewId, KNullUid, KNullDesC8 ); +#else + ActivateViewL( TVwsViewId( Application()->AppDllUid(), aViewId ) ); +#endif // RD_SPLIT_VIEW + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ActivateLocalViewL +// Activates a local view. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::ActivateLocalViewL( TUid aViewId, TUid aCustomMessageId, const TDesC8& aCustomMessage ) + { + ActivateViewL( TVwsViewId( Application()->AppDllUid(), aViewId ), aCustomMessageId, aCustomMessage ); + +#ifdef RD_SPLIT_VIEW + const TAknSplitViewContainer* splitView( SplitView( aViewId ) ); + if ( splitView ) + { + CAknEnv::Static()->SplitViewActive( ETrue ); + + if ( !ViewShown( splitView->iViewIds[0] ) || !ViewShown( splitView->iViewIds[1] ) ) + { + iExtension->iFlags |= EAknViewAppUiFromSingleToSplit; + } + } +#endif // RD_SPLIT_VIEW + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::HandleStatusPaneSizeChange +// Called by the framework when status pane's position or size changes. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::HandleStatusPaneSizeChange() + { + if (iClearer) + { + TRAP_IGNORE(iClearer->HandleStatusPaneSizeChangeL()); + } + + const TInt count( iViews->Count() ); + + for ( TInt i = 0; i < count; ++i ) + { + iViews->At( i )->HandleStatusPaneSizeChange(); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ViewActivatedL +// Adds a view to the activation queue. +// ----------------------------------------------------------------------------- +// +void CAknViewAppUi::ViewActivatedL( CAknView* aView, const TVwsViewId& aPrevViewId, TUid aCustomMessageId, const TDesC8& aCustomMessage ) + { + CViewActivationItem* activation( CViewActivationItem::NewLC( aView, aCustomMessageId, aCustomMessage, aPrevViewId ) ); + iActivationQueue->AppendL( activation ); + CleanupStack::Pop(); // activation + QueueActivationTick(); + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ViewDeactivated +// An empty implementation. +// ----------------------------------------------------------------------------- +// +void CAknViewAppUi::ViewDeactivated( CAknView* /*aView*/ ) + { + // SERIES60 apps always have at least one active view. + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::HandleForegroundEventL +// Called by the framework when view's foreground status changes. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::HandleForegroundEventL( TBool aForeground ) + { + CAknAppUi::HandleForegroundEventL( aForeground ); + + if ( iView ) + { + iView->ProcessForegroundEventL( aForeground ); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ActivationCallBack +// Callback function of idle timer iActivationTick. +// ----------------------------------------------------------------------------- +// +TInt CAknViewAppUi::ActivationCallBack( TAny* aThis ) + { + static_cast( aThis )->ActivationTick(); + + return 0; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ActivationTick +// Handles asynchronous view activation / deactivation. +// ----------------------------------------------------------------------------- +// +void CAknViewAppUi::ActivationTick() + { + CViewActivationItem* item( iActivationQueue->At( 0 ) ); +#ifndef RD_SPLIT_VIEW + iActivationQueue->Delete( 0 ); +#endif // !RD_SPLIT_VIEW + + TBool exit( EFalse ); + +#ifdef RD_SPLIT_VIEW + if ( !( iExtension->iFlags & EAknViewAppUiFromSplitToSingle ) && + !( iExtension->iFlags & EAknViewAppUiFromSingleToSplit ) && + item->iNewView == iView && + item->iCustomMessageId == KNullUid && + item->iCustomMessage->Length() == 0 ) + { + // Still in the same app view with no new message. + // No need for view switch. + } + else + { + TInt error( KErrNone ); + + const TAknSplitViewContainer* splitView( SplitView( item->iNewView->Id() ) ); + + if ( splitView ) + { + TRAP( error, ActivateSplitViewL( item ) ); + } + else if ( iExtension->iFlags & EAknViewAppUiFromSplitToSingle ) + { + CAknEnv::Static()->SplitViewActive( EFalse ); + item->iNewView->HandleViewRectChange(); + item->iNewView->Redraw(); + } + else + { + TRAP( error, item->iNewView->AknViewActivatedL( item->iPrevViewId, + item->iCustomMessageId, + *item->iCustomMessage ) ); + CAknEnv::Static()->SplitViewActive( EFalse ); + } + + iExtension->iFlags &= ~( EAknViewAppUiFromSplitToSingle | EAknViewAppUiFromSingleToSplit ); + + if ( error == KErrNone ) + { + if ( iView ) + { + // new view successfully activated, shut down the old one(s) + for ( TInt i = 0; i < iExtension->iActiveViews.Count(); i++ ) + { + if ( splitView ) + { + if ( iExtension->iSplitViews[i].IsPartOf( iExtension->iActiveViews[i]->Id() ) ) + { + iExtension->iActiveViews.Remove( i ); + --i; + } + } + else + { + if ( iExtension->iActiveViews[i] == item->iNewView ) + { + iExtension->iActiveViews.Remove( i ); + --i; + } + } + } + + iShutter->Start( iExtension->iActiveViews ); + + if ( iExtension->iActiveViews.Count() == 0 ) + { + iView->StopDisplayingMenuBar(); + } + } + + iExtension->iActiveViews.Reset(); + + // Number of views is always smaller than already reserved array + // (default granularity is 8) -> no memory allocation failures. + if ( splitView ) + { + iExtension->iActiveViews.Append( View( splitView->iViewIds[0] ) ); + iExtension->iActiveViews.Append( View( splitView->iViewIds[1] ) ); + } + else + { + iExtension->iActiveViews.Append( item->iNewView ); + } + + iView = item->iNewView; + } + else + { + // deactivate failed view(s) immediately + if ( splitView ) + { + CAknEnv::Static()->SplitViewActive( EFalse ); + + for ( TInt i = 0; i < KAknSplitViewSize; i++ ) + { + if ( splitView->iFailed[i] ) + { + CAknView* view( View( splitView->iViewIds[i] ) ); + + view->AknViewDeactivated(); + + TInt position( iExtension->iActiveViews.Find( view ) ); + + if ( position != KErrNotFound ) + { + iExtension->iActiveViews.Remove( position ); + } + } + } + } + else + { + item->iNewView->AknViewDeactivated(); + + TInt position( iExtension->iActiveViews.Find( item->iNewView ) ); + + if ( position != KErrNotFound ) + { + iExtension->iActiveViews.Remove( position ); + } + } + + // report error to the user + iEikonEnv->HandleError( error ); + + // recover the app as best possible + if ( !iView ) + { + // no view to fall back to -> exit + exit = ETrue; + } + else if ( iView == item->iNewView ) + { + // view reactivation failed -> forget current and try default + iView = NULL; + TVwsViewId viewId; + + if ( GetDefaultViewId( viewId ) == KErrNone ) + { + TRAP_IGNORE( ActivateViewL( viewId ) ); + } + else + { + exit = ETrue; + } + } + else + { + // tell the view server that we're staying here + TRAP_IGNORE( ActivateLocalViewL( iView->Id() ) ); + } + + // activation has failed, go back to the last view if in a different app + if ( item->iPrevViewId.iAppUid != Application()->AppDllUid() ) + { + TRAP_IGNORE( ActivateViewL( item->iPrevViewId ) ); + } + } + } +#else + if ( item->iNewView == iView && + item->iCustomMessageId == KNullUid && + item->iCustomMessage->Length() == 0 ) + { + // Still on the same app view, with no new message. + // No need for a app view switch. + } + else + { + if ( iView && CurrentPopupToolbar() ) + { + iView->SaveToolbarStatus(CurrentPopupToolbar()->IsShown(), !CurrentPopupToolbar()->IsNonFocusing() ); + } + + TRAPD( error, item->iNewView->AknViewActivatedL( item->iPrevViewId, + item->iCustomMessageId, + *item->iCustomMessage ) ); + + if ( error == KErrNone ) + { + // New view sucessfully activated. Shut down the old one. + if ( iView ) + { + if ( iView != item->iNewView ) // Is this really a new view? + { + iExtension->iActiveViews.Reset(); + iExtension->iActiveViews.Append( iView ); + iShutter->Start( iExtension->iActiveViews ); // Deactivate iView + } + else + { + iExtension->iActiveViews.Reset(); + iShutter->Start( iExtension->iActiveViews ); // Tidy up iView if it's not new + iView->StopDisplayingMenuBar(); + } + } + + iExtension->iActiveViews.Reset(); + iExtension->iActiveViews.Append( item->iNewView ); + iView = item->iNewView; + } + else + { + // deactivate failed view immediately + item->iNewView->AknViewDeactivated(); + + // report the error to the user + iEikonEnv->HandleError( error ); + + // recover the app as best possible + if ( !iView ) + { + // no view to fall back to - exit + exit = ETrue; + } + else if ( iView == item->iNewView ) + { + // Reactivation of view failed - forget current and try default view + iView = NULL; + TVwsViewId viewId; + + if ( GetDefaultViewId( viewId ) == KErrNone ) + { + TRAP_IGNORE( ActivateViewL( viewId ) ); + } + else + { + // no default view - exit + exit = ETrue; + } + } + else + { + // Tell view server that we're staying here + TRAP_IGNORE( ActivateLocalViewL( iView->Id() ) ); + } + + // This activation has failed, so go back to the last view if in a different app. + if ( item->iPrevViewId.iAppUid != Application()->AppDllUid() ) + { + TRAP_IGNORE( ActivateViewL( item->iPrevViewId ) ); + } + } + } +#endif // RD_SPLIT_VIEW + + delete iClearer; + iClearer = NULL; + +#ifdef RD_SPLIT_VIEW + iActivationQueue->Delete( 0 ); +#endif // RD_SPLIT_VIEW + delete item; + + if ( exit ) + { + TRAP_IGNORE( HandleForegroundEventL( EFalse ) ); + RunAppShutter(); + } + else + { + QueueActivationTick(); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::QueueActivationTick +// Starts the activation idle timer. +// ----------------------------------------------------------------------------- +// +void CAknViewAppUi::QueueActivationTick() + { + if ( iActivationQueue->Count() && !iActivationTick->IsActive() ) + { + iActivationTick->Start( TCallBack( ActivationCallBack, this ) ); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::StopDisplayingMenuBar +// Called by the framework when a possible menu bar should be dismissed. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::StopDisplayingMenuBar() + { + CAknAppUi::StopDisplayingMenuBar(); + + if ( iView ) + { + iView->StopDisplayingMenuBar(); + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::Extension +// Asserts that extension object has been created. +// ----------------------------------------------------------------------------- +// +CAknViewAppUiExtension* CAknViewAppUi::Extension() const + { + __ASSERT_ALWAYS( iExtension, Panic( EAknPanicObjectNotFullyConstructed ) ); + return iExtension; + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::SetSplitViewL +// Combines two views. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +EXPORT_C void CAknViewAppUi::SetSplitViewL( const TUid aView1Id, + const TUid aView2Id, + const TInt aLeftViewSize ) + { + // a view can belong to one split view only + RemoveSplitViewL( aView1Id ); + RemoveSplitViewL( aView2Id ); + + TAknSplitViewContainer splitView; + splitView.iViewIds[0] = aView1Id; + splitView.iViewIds[1] = aView2Id; + splitView.iLeftViewSize = aLeftViewSize; + + iExtension->iSplitViews.AppendL( splitView ); + } +#else +EXPORT_C void CAknViewAppUi::SetSplitViewL( const TUid /*aView1Id*/, + const TUid /*aView2Id*/, + const TInt /*aLeftViewSize*/ ) + { + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::RemoveSplitViewL +// Removes a view combination containing the given view UID. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +EXPORT_C void CAknViewAppUi::RemoveSplitViewL( const TUid aViewId ) + { + for ( TInt i = 0; i < iExtension->iSplitViews.Count(); i++ ) + { + if ( iExtension->iSplitViews[i].IsPartOf( aViewId ) ) + { + iExtension->iSplitViews.Remove( i ); + + if ( ViewShown( aViewId ) ) + { + iExtension->iFlags |= EAknViewAppUiFromSplitToSingle; + ActivateLocalViewL( aViewId ); + } + + return; + } + } + } +#else +EXPORT_C void CAknViewAppUi::RemoveSplitViewL( const TUid /*aViewId*/ ) + { + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::SplitViewActive +// Checks if split view is in use. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +EXPORT_C TBool CAknViewAppUi::SplitViewActive() const + { + if ( iActivationQueue->Count() > 0 ) + { + if ( SplitView( iActivationQueue->At( 0 )->iNewView->Id() ) ) + { + return ETrue; + } + } + + if ( iExtension->iFlags & EAknViewAppUiFromSplitToSingle ) + { + return EFalse; + } + + return iExtension->iActiveViews.Count() > 1; + } +#else +EXPORT_C TBool CAknViewAppUi::SplitViewActive() const + { + return EFalse; + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::FocusedView +// Returns the currently focused view. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +EXPORT_C TUid CAknViewAppUi::FocusedView() const + { + if ( iView ) + { + return iView->Id(); + } + + return KNullUid; + } +#else +EXPORT_C TUid CAknViewAppUi::FocusedView() const + { + return KNullUid; + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ViewShown +// Checks if the given view is visible on the screen. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +EXPORT_C TBool CAknViewAppUi::ViewShown( const TUid aViewId ) const + { + for ( TInt i = 0; i < iExtension->iActiveViews.Count(); i++ ) + { + if ( iExtension->iActiveViews[i]->Id() == aViewId ) + { + return ETrue; + } + } + + return EFalse; + } +#else +EXPORT_C TBool CAknViewAppUi::ViewShown( const TUid /*aViewId*/ ) const + { + return EFalse; + } +#endif // RD_SPLIT_VIEW + + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::EnableLocalScreenClearer +// Enables/disables local screen clearer. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::EnableLocalScreenClearer( TBool aEnable ) + { + // Make sure iExtension exists (can be called before BaseConstructL) + if ( !iExtension ) + { + TRAP_IGNORE( iExtension = CAknViewAppUiExtension::NewL() ); + } + + // Update flag + if ( iExtension ) + { + iExtension->iUseDefaultScreenClearer = aEnable; + } + + // Create/delete iClearer if required + if ( aEnable && !iClearer ) + { + TRAP_IGNORE( iClearer = CAknLocalScreenClearer::NewL( EFalse ) ); + } + else if ( !aEnable && iClearer ) + { + delete iClearer; + iClearer = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ViewRect +// Returns view's rectangle. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +TRect CAknViewAppUi::ViewRect( const TUid aViewId ) const + { + // Following code is used until layout data is available. Eventually it + // will be replaced by the commented code. + TRect rect( ClientRect() ); + const TAknSplitViewContainer* splitView( SplitView( aViewId ) ); + + if ( splitView ) + { + TInt leftWidth( rect.Width() * splitView->iLeftViewSize / 100 ); + + if ( splitView->iViewIds[0] == aViewId ) + { + rect.SetWidth( leftWidth ); + } + else + { + rect.SetWidth( rect.Width() - leftWidth ); + rect.Move( leftWidth, 0 ); + } + } + + return rect; + +/* const TAknSplitViewContainer* splitView( SplitView( aViewId ) ); + + if ( splitView) + { + TAknLayoutRect viewRect; + + if ( splitView->iViewIds[0] == aViewId ) // left view + { + viewRect.LayoutRect( ApplicationRect(), AknLayoutScalable_Avkon::main_pane( 8 ) ); + } + else // right view + { + viewRect.LayoutRect( ApplicationRect(), AknLayoutScalable_Avkon::main_pane_cp() ); + } + + return viewRect.Rect(); + } + + return ClientRect();*/ + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::SplitView +// If the given view is part of a split view then returns that split view. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +CAknViewAppUi::TAknSplitViewContainer* CAknViewAppUi::SplitView( const TUid aViewId ) const + { + for ( TInt i = 0; i < iExtension->iSplitViews.Count(); i++ ) + { + if ( iExtension->iSplitViews[i].IsPartOf( aViewId ) ) + { + return &iExtension->iSplitViews[i]; + } + } + + return NULL; + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::ActivateSplitViewL +// Activates views in split view. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +void CAknViewAppUi::ActivateSplitViewL( CViewActivationItem* aItem ) + { + TAknSplitViewContainer* splitView( SplitView( aItem->iNewView->Id() ) ); + + splitView->iFailed[0] = ETrue; + splitView->iFailed[1] = ETrue; + + for ( TInt i = 0; i < KAknSplitViewSize; i++ ) + { + TRect viewRect( ViewRect( splitView->iViewIds[i] ) ); + + if ( ViewShown( splitView->iViewIds[i] ) ) + { + if ( splitView->iViewRect[i] != viewRect ) + { + splitView->iViewRect[i] = viewRect; + View( splitView->iViewIds[i] )->HandleViewRectChange(); + } + + View( splitView->iViewIds[i] )->Redraw(); + } + else + { + View( splitView->iViewIds[i] )->AknViewActivatedL( aItem->iPrevViewId, + aItem->iCustomMessageId, + *aItem->iCustomMessage ); + splitView->iViewRect[i] = viewRect; + } + + splitView->iFailed[i] = EFalse; + } + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::HandleViewNavigationL +// Handles navigation between visible split views. +// ----------------------------------------------------------------------------- +// +#ifdef RD_SPLIT_VIEW +TKeyResponse CAknViewAppUi::HandleViewNavigationL( const TKeyEvent& aKeyEvent ) + { + if ( SplitViewActive() ) + { + switch ( aKeyEvent.iCode ) + { + case EKeyLeftArrow: + case EKeyRightArrow: + case EKeyTab: + if ( iView == iExtension->iActiveViews[0] ) + { + ActivateLocalViewL( iExtension->iActiveViews[1]->Id() ); + } + else + { + ActivateLocalViewL( iExtension->iActiveViews[0]->Id() ); + } + + return EKeyWasConsumed; + + default: + break; + } + } + + return EKeyWasNotConsumed; + } +#endif // RD_SPLIT_VIEW + +// ----------------------------------------------------------------------------- +// CAknViewAppUi::HandleWsEventL +// Handles pointer-initiated view switch. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAknViewAppUi::HandleWsEventL( const TWsEvent& aEvent, CCoeControl* aDestination ) + { +#ifdef RD_SPLIT_VIEW + if ( AknLayoutUtils::PenEnabled() ) + { + if ( SplitViewActive() && aEvent.Type() == EEventPointer && !IsDisplayingMenuOrDialog() ) + { + switch ( aEvent.Pointer()->iType ) + { + case TPointerEvent::EButton1Down: + for ( TInt i = 0; i < iExtension->iActiveViews.Count(); i++ ) + { + if ( iView == iExtension->iActiveViews[i] ) + { + if ( iExtension->iActiveViews[i^1]->ClientRect().Contains( aEvent.Pointer()->iParentPosition ) ) + { + iExtension->iFlags |= i + 1; + break; + } + } + } + break; + + case TPointerEvent::EButton1Up: + for ( TInt i = 0; i < iExtension->iActiveViews.Count(); i++ ) + { + if ( iView == iExtension->iActiveViews[i] ) + { + if ( iExtension->iActiveViews[i^1]->ClientRect().Contains( aEvent.Pointer()->iParentPosition ) && + iExtension->iFlags & i + 1 ) + { + ActivateLocalViewL( iExtension->iActiveViews[i^1]->Id() ); + break; + } + } + } + + iExtension->iFlags &= ~( EAknViewAppUiButton1DownInLeft | EAknViewAppUiButton1DownInRight ); + break; + + default: + break; + } + } + } +#endif // RD_SPLIT_VIEW + CAknAppUi::HandleWsEventL( aEvent, aDestination ); + } + +// End of File