/*
* Copyright (c) 2002-2010 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 <eikbtgpc.h>
#include <avkon.rsg>
#include <avkon.hrh>
#include <eikenv.h>
#include <eikmenub.h>
#include <eikcolib.h>
#include <eikapp.h>
#include <aknclearer.h>
#include <AknUtils.h>
#include <akntoolbar.h>
#include <akntranseffect.h>
#include <centralrepository.h>
#include "aknview.h"
#include "aknshut.h"
#include "aknenv.h"
#include "AknPanic.h"
#ifdef RD_SPLIT_VIEW
#include "AknViewNavigator.h"
#include <aknsutils.h>
#include <aknsdrawutils.h>
#include <AknLayoutScalable_Avkon.cdl.h>
#include <LayoutMetaData.cdl.h>
#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<CAknView> iActiveViews;
#ifdef RD_SPLIT_VIEW
RArray<CAknViewAppUi::TAknSplitViewContainer> 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
// Only clear the window for foreground apps.
if ( iEikonEnv->RootWin().OrdinalPosition() == 0 &&
iExtension->iUseDefaultScreenClearer )
{
if ( !iEikonEnv->StartedAsServerApp() )
{
iClearer = CAknLocalScreenClearer::NewL( ETrue );
}
else
{
iClearer = CAknLocalScreenClearer::NewL( ETrue, ETrue );
}
}
}
// -----------------------------------------------------------------------------
// CAknViewAppUi::~CAknViewAppUi
// Destructor.
// -----------------------------------------------------------------------------
//
EXPORT_C CAknViewAppUi::~CAknViewAppUi()
{
#ifdef RD_SPLIT_VIEW
if (iExtension && iExtension->iNavigator )
RemoveFromStack( iExtension->iNavigator );
#endif // RD_SPLIT_VIEW
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<CAknViewAppUi*>( 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