/*
* Copyright (c) 2002-2009 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: Control container for fastswap.
*
*/
// INCLUDE FILES
#include <gulicon.h>
#include <eikbtgpc.h>
#include <eikmop.h>
#include <AknQueryDialog.h>
#include <eiksrvui.rsg>
#include <StringLoader.h>
#include <AknsDrawUtils.h>
#include <AknsControlContext.h>
#include <avkon.mbg>
#include <AknsFrameBackgroundControlContext.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <layoutmetadata.cdl.h>
#include <AknIconUtils.h>
#include <eikfrlbd.h>
#include <apgwgnam.h>
#include <AknInfoPopupNoteController.h> // tooltip
#include <AknBidiTextUtils.h> // method ConvertToVisualAndClipL
#include <skinlayout.cdl.h>
#include <akntransitionutils.h>
#include <akntranseffect.h>
#include <gfxtranseffect/gfxtranseffect.h>
#include <widgetregistryconstants.h>
#include <widgetregistrydata.h>
#include <featmgr.h>
#include <aknglobalpopupprioritycontroller.h>
#include <centralrepository.h>
#include <AknTasHook.h>
#include <touchfeedback.h>
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
#include <aknlistloadertfx.h>
#include <aknlistboxtfxinternal.h>
#endif // RD_UI_TRANSITION_EFFECTS_LIST
#include <aknmemorycardui.rsg>
#include <aknlongtapanimation.h>
#include <aknstyluspopupmenu.h>
#include <aknpointereventsuppressor.h>
#include <pslninternalcrkeys.h>
#include <AknStatuspaneUtils.h>
#include "AknFastswapWindowControl.h"
#include "AknFastswapWindowGrid.h"
#include "AknCapServerEntry.h"
#include "akntrace.h"
void InvalidateWindows( CCoeControl* aControl )
{
if ( aControl )
{
if ( aControl->OwnsWindow() )
{
( (RWindow*) aControl->DrawableWindow() )->ClearRedrawStore();
}
for ( TInt i = aControl->CountComponentControls() - 1; i >= 0; --i )
{
InvalidateWindows( aControl->ComponentControl( i ) );
}
}
}
const TInt KFSWArrayGranularity = 4;
const TInt KMinimumSupportedApps = 20;
const TBool KVerticalOrientation = EFalse;
const TBool KLeftToRight = ETrue;
const TBool KRightToLeft = EFalse;
const TBool KTopToBottom = ETrue;
const TInt KTooltipTimeBefore = 600;
const TInt KTooltipTimeView = 1500;
// Values for touch mode tooltip.
const TInt KTooltipTimeBeforeTouch = 0;
const TInt KTooltipTimeViewTouch = 0; // Shown until canceled
// Always shown applications spesified in the ui specs.
const TInt KAlwaysShownAppCount = 3;
const TUid KMenuAppUid = {0x101F4CD2};
const TUid KSearchAppUid = {0x0EFC346A};
// new idle from 3.2 onwards, old idle uid is 0x101FD64C
const TUid KIdleAppUid = {0x102750F0};
const TInt KApplicationWithoutWG = KErrNotFound;
const TInt KWidgetWithoutWG = KErrGeneral;
// Uid of the Widget application.
const TUid KWidgetAppUid = {0x10282822};
// Matrix Menu P&S category
const TUid KFSWMMenuPSCat = {0x101F4CD2};
// Key that stores last used - current view (it is text value)
const TUint KFSWMMenuLastViewKey = 0x01;
// name of folder view
_LIT(KFSWMMenuFolderView, "foldersuite");
const TInt KTimeDelayBeforeAnimation = 200000; // 0.2 seconds
const TInt KLongTapDelay = 800000; // 0.8 seconds
const TInt KTimeNeverHappenEvent = 100000000; // 100 seconds
const TInt KPressedDownEffectTime = 500000;//0.5 seconds
enum TAknCapServerCommands
{
EAknCapServerCmdOpen = 0x6100,
EAknCapServerCmdClose
};
NONSHARABLE_CLASS(CAknFastSwapData) : public CBase,
public MAknTransitionUtilsObserver
{
public:
CAknFastSwapData(TInt aKey, CAknInfoPopupNoteController* aTooltip);
private:
TInt AknTransitionCallback(TInt aEvent, TInt aState = 0,
const TDesC8* aParams = NULL);
private:
CAknInfoPopupNoteController* iTooltip;
TInt iKey;
};
CAknFastSwapData::CAknFastSwapData( TInt aKey,
CAknInfoPopupNoteController* aTooltip )
: iTooltip( aTooltip ), iKey( aKey )
{
}
TInt CAknFastSwapData::AknTransitionCallback(TInt aEvent, TInt /*aState*/,
const TDesC8* /*aParams*/)
{
_AKNTRACE_FUNC_ENTER;
iTooltip->ShowInfoPopupNote();
CAknTransitionUtils::RemoveObserver( this, aEvent );
_AKNTRACE_FUNC_EXIT;
return KErrNone;
}
NONSHARABLE_CLASS(CAknWidgetList) : public CBase
{
public:
static CAknWidgetList* NewL( CAknFastSwapWindowControl& aParent );
/** Destructor */
~CAknWidgetList();
/**
* Initializes the list that stores widgets.
* @return -
*/
void InitializeWidgetListL();
/**
* Check if a uid is the uid of the widget application.
* @param aAppUid The application uid to be checked.
* @return ETrue application uid belongs to widget application - EFalse otherwise.
*/
TBool IsWidgetAppUI( TUid aAppUid );
/**
* Check if the window group id value refers to widget.
* @param aWgId window group id.
* @return ETrue if window group id has value that refers to widget.
*/
TBool IsWidget( TInt aWgId );
/**
* Map tasklist application index to application Uid.
*
* @param aIndex index of tasklist item array.
* @param aAlwaysShownCount number of applications that are always shown on
the active applications list.
* @return application Uid
*/
TUid IndexToAppUid( TInt aIndex, TInt aAlwaysShownCount );
private:
/** Constructor */
CAknWidgetList( CAknFastSwapWindowControl& aParent );
void ConstructL();
void ResetArrayOfWidgetInfo( RWidgetInfoArray& aWidgetInfoArr );
static void CleanupConnect( TAny* aThis );
public:
/** Contains list of widgets that are currently running */
RWidgetInfoArray iRunningWidgets;
private:
CAknFastSwapWindowControl& iParent;
RWidgetRegistryClientSession iWidgetRegistryClientSession;
};
CAknWidgetList* CAknWidgetList::NewL( CAknFastSwapWindowControl& aParent )
{
_AKNTRACE_FUNC_ENTER;
CAknWidgetList* self = new (ELeave) CAknWidgetList( aParent );
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); //self
_AKNTRACE_FUNC_EXIT;
return self;
}
CAknWidgetList::CAknWidgetList( CAknFastSwapWindowControl& aParent ): iParent( aParent )
{
}
CAknWidgetList::~CAknWidgetList()
{
_AKNTRACE_FUNC_ENTER;
ResetArrayOfWidgetInfo( iRunningWidgets );
iRunningWidgets.Reset();
_AKNTRACE_FUNC_EXIT;
}
void CAknWidgetList::ConstructL()
{
}
void CAknWidgetList::CleanupConnect( TAny* aThis )
{
_AKNTRACE_FUNC_ENTER;
(( CAknWidgetList*)aThis)->iWidgetRegistryClientSession.Disconnect();
_AKNTRACE_FUNC_EXIT;
}
void CAknWidgetList::InitializeWidgetListL()
{
_AKNTRACE_FUNC_ENTER;
ResetArrayOfWidgetInfo( iRunningWidgets );
iRunningWidgets.Reset();
User::LeaveIfError( iWidgetRegistryClientSession.Connect() );
CleanupStack::PushL( TCleanupItem( CleanupConnect, this) );
iWidgetRegistryClientSession.RunningWidgetsL(iRunningWidgets);
for ( TInt i = iRunningWidgets.Count() - 1; i > -1; i-- )
{
if ( !iWidgetRegistryClientSession.IsWidgetInFullView(iRunningWidgets[i]->iUid) )
{
delete iRunningWidgets[i];
iRunningWidgets.Remove(i);
}
}
CleanupStack::Pop(); // clean WidgetRegistryClientSession item
iWidgetRegistryClientSession.Disconnect();
_AKNTRACE_FUNC_EXIT;
}
TBool CAknWidgetList::IsWidgetAppUI( TUid aAppUid )
{
_AKNTRACE( "[%s] aAppUid = %d",
__FUNCTION__, aAppUid.iUid );
return (aAppUid == KWidgetAppUid);
}
TBool CAknWidgetList::IsWidget( TInt aWgId )
{
_AKNTRACE( "[%s] aWgId = %d",
__FUNCTION__, aWgId );
return (aWgId == KWidgetWithoutWG);
}
TUid CAknWidgetList::IndexToAppUid( TInt aIndex, TInt aAlwaysShownCount )
{
_AKNTRACE( "[%s] aIndex = %d aAlwaysShownCount = %d",
__FUNCTION__, aIndex, aAlwaysShownCount );
return iRunningWidgets[aIndex + iRunningWidgets.Count() +
aAlwaysShownCount - iParent.iNumberOfWGs]->iUid;
}
void CAknWidgetList::ResetArrayOfWidgetInfo(
RWidgetInfoArray& aWidgetInfoArr )
{
_AKNTRACE_FUNC_ENTER;
for ( TInt i = 0; i < aWidgetInfoArr.Count(); i++ )
{
CWidgetInfo *item = aWidgetInfoArr[i];
delete item ;
}
_AKNTRACE_FUNC_EXIT;
}
NONSHARABLE_CLASS(CAknAlwaysShownAppList) : public CBase
{
public:
// always shown application info
// used in the always shown application list
struct SAlwaysShownAppInfo
{
TUid iAppUid;
TInt iWgId;
};
public:
static CAknAlwaysShownAppList* NewL( CAknFastSwapWindowControl& aParent );
CAknAlwaysShownAppList( CAknFastSwapWindowControl& aParent );
~CAknAlwaysShownAppList();
/**
* Initializes the list that stores applications that are always
* shown in the fast swap provided they have been installed
* in the phone rom
* @return -
*/
void InitializeAlwaysShownListL();
/**
* Add window group id to spesific appication (=uid)
* @return -
* @param TUid aAppUid the application uid
* @param TInt aWgId the window group where task resides
*/
void AddWgGroupToAlwaysShownList( TUid aAppUid, TInt aWgId );
/**
* If application uid exists in the always shown application list
* @return ETrue application uid exists in the list
* EFalse application uid doesn't exist in the list
* @param TUid aAppUid the application uid
*/
TBool IsAlwaysShownApp( TUid aAppUid );
/**
* If application window group exists in the always shown application list
* @return ETrue wg exists in the list
* EFalse wg doesn't exist in the list
* @param TInt aWgId the application window group
*/
TBool IsAlwaysShownApp( TInt aWgId );
/**
*
* Map Tasklist application index to application Uid
* @return TUid application Uid
*
* @param TInt aIndex index of tasklist item arrays
*/
TUid IndexToAppUid( TInt aIndex );
public:
RArray<SAlwaysShownAppInfo>* iAppList;
private:
void ConstructL();
private:
// the list of applications always shown in the fsw
CAknFastSwapWindowControl& iParent;
};
// ---------------------------------------------------------
// CAknFastSwapWindowControl::NewL
// ---------------------------------------------------------
//
CAknAlwaysShownAppList* CAknAlwaysShownAppList::NewL( CAknFastSwapWindowControl& aParent )
{
_AKNTRACE_FUNC_ENTER;
CAknAlwaysShownAppList* self = new (ELeave) CAknAlwaysShownAppList( aParent );
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); //self
_AKNTRACE_FUNC_EXIT;
return self;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CAknAlwaysShownAppList
// ---------------------------------------------------------
//
CAknAlwaysShownAppList::CAknAlwaysShownAppList( CAknFastSwapWindowControl& aParent )
: iParent( aParent )
{
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::~CAknAlwaysShownAppList
// ---------------------------------------------------------
//
CAknAlwaysShownAppList::~CAknAlwaysShownAppList()
{
_AKNTRACE_FUNC_ENTER;
if (iAppList)
{
iAppList->Close();
}
delete iAppList;
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::ConstructL
// ---------------------------------------------------------
//
void CAknAlwaysShownAppList::ConstructL()
{
// the list for always shown applications in the fast swap
iAppList = new (ELeave) RArray<SAlwaysShownAppInfo>();
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::InitializeAlwaysShownListL
// Applications that are always shown in fast swap are stored
// in different their own list whether they exist
// in the phone rom or not
// ---------------------------------------------------------
//
void CAknAlwaysShownAppList::InitializeAlwaysShownListL()
{
_AKNTRACE_FUNC_ENTER;
iAppList->Close();
// order of always shown applications
TUid uidArray[] = {KMenuAppUid, KSearchAppUid, KIdleAppUid};
TApaAppInfo applicationInfo;
SAlwaysShownAppInfo fixedAppInfo;
for ( TInt index = 0; index < KAlwaysShownAppCount; index++)
{
// if exists in phone rom
if ( iParent.iAppArcSession.GetAppInfo(applicationInfo, uidArray[index]) != KErrNotFound )
{
fixedAppInfo.iAppUid = uidArray[index];
// list is created without known window groups
fixedAppInfo.iWgId = KApplicationWithoutWG;
iAppList->AppendL( fixedAppInfo );
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::AddWgGroupToAlwaysShownList
// The window groups are stored with the application uids
// ---------------------------------------------------------
//
void CAknAlwaysShownAppList::AddWgGroupToAlwaysShownList( TUid aAppUid, TInt aWgId )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aAppUid = %d aWgId = %d",
__FUNCTION__, aAppUid.iUid, aWgId );
for ( TInt index = 0; index < iAppList->Count(); index++)
{
if ( (*iAppList)[index].iAppUid == aAppUid )
{
(*iAppList)[index].iWgId = aWgId;
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::IsAlwaysShownApp
// If application uid exists in the always shown application list
// ---------------------------------------------------------
//
TBool CAknAlwaysShownAppList::IsAlwaysShownApp( TUid aAppUid )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aAppUid = %d", __FUNCTION__, aAppUid.iUid );
for ( TInt index = 0; index < iAppList->Count(); index++)
{
if ( (*iAppList)[index].iAppUid == aAppUid )
{
_AKNTRACE_FUNC_EXIT;
return ETrue;
}
}
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::IsAlwaysShownApp
// If application window group exists in the always shown application list
// ---------------------------------------------------------
//
TBool CAknAlwaysShownAppList::IsAlwaysShownApp( TInt aWgId )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aWgId = %d", __FUNCTION__, aWgId );
for ( TInt index = 0; index < iAppList->Count(); index++)
{
if ( (*iAppList)[index].iWgId == aWgId )
{
_AKNTRACE_FUNC_EXIT;
return ETrue;
}
}
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::IndexToAppUid
// Map Tasklist application index to application Uid
// ---------------------------------------------------------
//
TUid CAknAlwaysShownAppList::IndexToAppUid( TInt aIndex )
{
_AKNTRACE( "[%s] aIndex = %d", __FUNCTION__, aIndex );
return (*iAppList)[aIndex + iAppList->Count() - iParent.iNumberOfWGs].iAppUid;
}
CAknGridView::TScrollingType KVerticalScrollingType = CAknGridView::EScrollFollowsItemsAndLoops;
CAknGridView::TScrollingType KHorizontalScrollingType = CAknGridView::EScrollFollowsItemsAndLoops;
_LIT(KTab,"\t");
// ================= MEMBER FUNCTIONS =======================
// C++ default constructor can NOT contain any code, that
// might leave.
//
CAknFastSwapWindowControl::CAknFastSwapWindowControl(CAknCapAppServerAppUi& aAppUi)
: iAppUi( aAppUi ),iLowMemory( EFalse ), iLowMemIcons( EFalse ), iAppArcSessionInitiated( EFalse ),
iWidgetAppUiWgId(-1), iWidgetsSupported( EFalse ),
iTooltipModeTouch( EFalse ),iTransparencyEnabled( CAknEnv::Static()->TransparencyEnabled() ),
iIsStylusPopupShow(EFalse), iState( EWaiting )
{
AKNTASHOOK_ADD( this, "CAknFastSwapWindowControl" );
}
// Symbian OS default constructor can leave.
void CAknFastSwapWindowControl::ConstructL()
{
_AKNTRACE_FUNC_ENTER;
GfxTransEffect::Enable();
CreateWindowL();
SetComponentsToInheritVisibility();
Window().SetShadowDisabled( ETrue );
Window().SetPointerGrab( ETrue );
SetGloballyCapturing( ETrue );
if( iTransparencyEnabled )
{
Window().SetRequiredDisplayMode( EColor16MA );
TInt err = Window().SetTransparencyAlphaChannel();
if ( err == KErrNone )
{
Window().SetBackgroundColor(~0);
}
}
if (FeatureManager::FeatureSupported(KFeatureIdWebWidgets))
{
iWidgetsSupported = ETrue;
}
CreateCbaL();
CreateGridL();
CreateItemArraysL();
CreateTooltipL();
CreateLabelL();
UpdateHeadingIconL();
//create animation
iLongTapAnimation = CAknLongTapAnimation::NewL( EFalse );
iThemesAppRepository = CRepository::NewL( KCRUidThemes );
//create TimeOut
iTimeOut = CPeriodic::NewL(CActive::EPriorityStandard);
iToolTipTimer = CPeriodic::NewL(CActive::EPriorityStandard);
CreateComponentArrayL();
// create control context
TRect nullRect( 0, 0 , 0, 0 );
iFrameContext = CAknsFrameBackgroundControlContext::NewL(
KAknsIIDQsnFrPopup, nullRect, nullRect, EFalse);
// the list for always shown applications in the fast swap
iAlwaysShownList = CAknAlwaysShownAppList::NewL( *this );
if (iWidgetsSupported)
{
iWidgetList = CAknWidgetList::NewL( *this );
}
MakeVisible( EFalse );
_AKNTRACE_FUNC_EXIT;
}
// Destructor
CAknFastSwapWindowControl::~CAknFastSwapWindowControl()
{
_AKNTRACE_FUNC_ENTER;
AKNTASHOOK_REMOVE();
AknGlobalPopupPriorityController::RemovePopupPriority(*this);
GfxTransEffect::Deregister( this );
iAppArcSession.Close();
ClearItemArrays( ETrue );
if ( iGrid )
{
AknsUtils::DeregisterControlPosition( iGrid );
}
delete iAlwaysShownList;
delete iWidgetList;
FadeBackground( EFalse );
delete iFrameContext;
delete iGrid; // destroys also iIconArray and scrollbar frame
delete iShownWgIds;
if ( iAllWgIds )
{
iAllWgIds->Close();
}
CAknFastSwapData *data =
(CAknFastSwapData*)CAknTransitionUtils::GetData( (TInt)this );
if ( data )
{
CAknTransitionUtils::RemoveObserver( data,
CAknTransitionUtils::EEventControlTransitionFinished );
CAknTransitionUtils::RemoveData( (TInt)this );
delete data;
}
delete iItemTextArray;
delete iAllWgIds;
delete iDefaultAppIcon;
delete iCba;
delete iConfirmCloseDialog;
delete iHeadingIcon;
delete iTooltip;
delete iLabel;
delete iPopupMenu;
delete iLongTapAnimation;
delete iTimeOut;
delete iToolTipTimer;
delete iThemesAppRepository;
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::RunFastSwapL
// Function that is called from CEikServAppUi to launch
// task switching. Updates all relevant data (see more detailed
// description from the functions called) and brings the
// window to foreground
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::RunFastSwapL()
{
_AKNTRACE_FUNC_ENTER;
if ( iIsDisplayed )
{
_AKNTRACE_FUNC_EXIT;
return;
}
TInt effectValue( 0 );
iThemesAppRepository->Get( KThemesTransitionEffects, effectValue );
if ( effectValue == 0 ) /* TAT on */
{
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
feedback->InstantFeedback( ETouchFeedbackIncreasingPopUp );
}
}
GfxTransEffect::Register( this, KGfxTaskSwapperControlUid, EFalse );
GfxTransEffect::Abort();
TPoint dPoint( iGrid->PositionRelativeToScreen() );
TRect dRect( iGrid->Rect() );
dRect.Move( dPoint );
SetPointerCapture( ETrue );
CleanupStack::PushL( TCleanupItem( CleanupRunFastSwap, this) );
iIsDisplayed = ETrue;
AknGlobalPopupPriorityController::AddPopupToControlStackL(*this,ECoeStackPriorityDialog,0 );
AknGlobalPopupPriorityController::AddPopupToControlStackL(*iCba->ButtonGroup()->AsControl(),
ECoeStackPriorityCba, ECoeStackFlagRefusesFocus );
AknGlobalPopupPriorityController::ShowPopup(*this, ETrue);
TBool areWeInIdleState = CEikStatusPaneBase::Current()->PaneCapabilities(
TUid::Uid( EEikStatusPaneUidClock ) ).IsInCurrentLayout();
if (areWeInIdleState)
{ // idle state
( (CEikCba*) iCba->ButtonGroup() )->SetSkinBackgroundId(KAknsIIDQsnBgAreaControlIdle);
}
else
{
( (CEikCba*) iCba->ButtonGroup() )->SetSkinBackgroundId(KAknsIIDQsnBgAreaControl);
}
iCba->HandleResourceChange(KEikDynamicLayoutVariantSwitch);
iCba->MakeVisible( ETrue );
SetRect( FastSwapWindowRect() ); // Causes call of SizeChanged()
iBackgroundWgId = (*iAllWgIds)[0].iId; // where to switch if cancel is pressed
ActivateL();
CleanupStack::Pop(); // clean fast swap cleanup item
// if the grid creation failed, fsw closes
if ( iGrid->Model()->NumberOfItems() == 0 )
{
// if memory runs out, FSW uses what it has
// and continues (should never happen)
CloseFastSwap();
}
else
{
iGrid->SetTopItemIndex( 0 );
iGrid->SetCurrentDataIndex( 0 );
UpdateTooltipL();
if ( !CAknTransitionUtils::TransitionsEnabled(
AknTransEffect::EComponentTransitionsOff ) )
{
iTooltip->ShowInfoPopupNote();
}
}
CAknTransitionUtils::SetAllParents( this );
TBool rsWasEnabled( EFalse );
if( !iTransparencyEnabled && Window().IsRedrawStoreEnabled() )
{
rsWasEnabled = ETrue;
// disable redrawstore during transition to avoid
// drawing problems behind FSW
Window().EnableRedrawStore( EFalse );
}
GfxTransEffect::Begin( this, KGfxControlAppearAction );
GfxTransEffect::NotifyExternalState(ECaptureComponentsBegin, (const TDesC8*)this);
// Temporarily set to nonfading to prevent a faded version
// from appearing on screen
Window().SetNonFading(ETrue);
FadeBackground( ETrue );
MakeVisible( ETrue );
SetFocus( ETrue );
Window().SetNonFading(EFalse);
GfxTransEffect::SetDemarcation( this, dRect );
CAknTransitionUtils::MakeVisibleSubComponents( this,
CAknTransitionUtils::EForceVisible );
// Delay display of tooltip until the appear animation has finished,
// to avoid the fast swap window being drawn on top of the tooltip.
CAknFastSwapData *data =
(CAknFastSwapData*)CAknTransitionUtils::GetData( (TInt)this );
if ( !data )
{
data = new (ELeave) CAknFastSwapData( (TInt)this, iTooltip );
CAknTransitionUtils::SetData( (TInt)this, data );
}
if ( CAknTransitionUtils::AddObserver( data,
CAknTransitionUtils::EEventControlTransitionFinished,
(const TDesC8 *)this ) == KErrNone )
{
GfxTransEffect::NotifyExternalState(ECaptureComponentsEnd, (const TDesC8*)this);
GfxTransEffect::End( this );
}
else
{
CAknTransitionUtils::RemoveData( (TInt)this );
delete data;
GfxTransEffect::Deregister( this );
}
if( !iTransparencyEnabled && rsWasEnabled )
{
// if redrawstore was on before transition,
// enable it again
Window().EnableRedrawStore( ETrue );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::HandleChangeInWindowGroupListL
// Function that is called from CEikServAppUi when apps list changes.
// Resets window size and selection if FSW is displayed.
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::HandleChangeInWindowGroupListL()
{
_AKNTRACE_FUNC_ENTER;
if ( !iIsDisplayed )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( iNumberOfWGs <= 0 )
{
CloseFastSwap();
_AKNTRACE_FUNC_EXIT;
return;
}
TInt currPos = iGrid->CurrentDataIndex();
SetRect( FastSwapWindowRect() ); // Causes call of SizeChanged()
TInt iOrgWgId = iBackgroundWgId;
TInt count = iAllWgIds->Count();
for ( TInt ii=0; ii<count && !IsWgIdInShownList( iBackgroundWgId); ii++ )
{
iBackgroundWgId = (*iAllWgIds)[ii].iId;
}
if ( iBackgroundWgId != iOrgWgId )
{
// If the current application is closed when hidden
// BeginFullScreen is called, we must abort that BeginFullScreen
GfxTransEffect::AbortFullScreen();
}
if ( iConfirmCloseDialog && !IsWgIdInShownList( iConfirmCloseWgId) )
{
delete iConfirmCloseDialog;
iConfirmCloseDialog = NULL;
}
// if the grid creation failed, fsw closes
if ( iGrid->Model()->NumberOfItems() == 0 )
{
// if memory runs out, FSW uses what it has
// and continues
CloseFastSwap();
}
else
{
if (currPos >= iGrid->Model()->NumberOfItems())
{
currPos = iGrid->Model()->NumberOfItems()-1;
}
iGrid->SetCurrentDataIndex(currPos);
ShowTooltipTouchL(EFalse);
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::InitializeWindowGroupListL
// Accesses the window server for a list of existing window groups
// of the standard window group priority (default for an application).
// Removes all hidden window groups from the list.
// Normally an application does not have more than one window group.
// ---------------------------------------------------------
//
TBool CAknFastSwapWindowControl::InitializeWindowGroupListL( TInt aWaitForWGRemoval )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aWaitForWGRemoval = %d", __FUNCTION__, aWaitForWGRemoval );
if (!iAppArcSessionInitiated)
{
// Creates a session to the apparc server,
// connection takes time, so done only once
// no need to do it many times
// done here because cannot be done at the startup
User::LeaveIfError( iAppArcSession.Connect() );
iAppArcSessionInitiated = ETrue;
}
iAppArcSession.GetAllApps();
// create list for always shown applications
iAlwaysShownList->InitializeAlwaysShownListL();
if (iWidgetsSupported)
{
iWidgetList->InitializeWidgetListL();
}
//Initializes CAknFastSwapWindowControl private data ( iWgIds, iNumberOfWGs )
RWsSession& wsSession=iEikonEnv->WsSession();
TInt count=wsSession.NumWindowGroups( 0 );
RArray<RWsSession::TWindowGroupChainInfo>* allWgIds = new (ELeave)
RArray<RWsSession::TWindowGroupChainInfo>( KFSWArrayGranularity );
CleanupDeletePushL( allWgIds );
CleanupClosePushL( *allWgIds );
User::LeaveIfError( wsSession.WindowGroupList( 0, allWgIds) );
count = allWgIds->Count();
CArrayFixFlat<SWindowGroupInfo>* shownWgIds = new (ELeave)
CArrayFixFlat<SWindowGroupInfo>(KFSWArrayGranularity);
CleanupStack::PushL(shownWgIds);
CApaWindowGroupName* windowName;
//
// Running application window groups
//
TInt firstAppWgId = KErrNone;
for ( TInt index=0; index < count; index++ )
{
RWsSession::TWindowGroupChainInfo& info = (*allWgIds)[index];
if ( info.iParentId <= 0 )
{
TInt wgId=info.iId;
windowName = CApaWindowGroupName::NewLC(wsSession, wgId);
TUid applicationUid = windowName->AppUid();
// application screen (0 = main screen, 1 = cover ui )
// the possible error value is omitted
TInt appScreen = -1;
TInt errId = iAppArcSession.GetDefaultScreenNumber( appScreen, applicationUid );
if ( errId != KErrNone )
{
CleanupStack::PopAndDestroy( windowName ); //windowName
continue;
}
if ( firstAppWgId == KErrNone && ( appScreen == 0 || appScreen == -1 ) )
{
firstAppWgId = wgId;
}
// always shown applications are appended to the end of window group list
if ( iAlwaysShownList->IsAlwaysShownApp( applicationUid ) )
{
iAlwaysShownList->AddWgGroupToAlwaysShownList( applicationUid, wgId );
}
else if (iWidgetsSupported && iWidgetList->IsWidgetAppUI(applicationUid))
{
iWidgetAppUiWgId = wgId;
}
// could't use windowName->IsAppReady(), because then java and console application
// wouldn't be seen in FSW. Now it is possible that some system apps are seen at the
// beginning of their start for a while in FSW (even they should be hidden all the time)
// temporary solution since application shell is normally hidden from tasklist
// and in the new solution it should be shown
else if ( !windowName->Hidden() && !iAppUi.HiddenFromFSW(applicationUid.iUid) &&
( appScreen == 0 || appScreen == -1 ) ) // appScreen == -1 is used for console applications
{
SWindowGroupInfo wgInfo = { wgId, windowName->IsSystem() };
shownWgIds->AppendL(wgInfo);
}
CleanupStack::PopAndDestroy(); //windowName
}
}
if (iWidgetsSupported)
{
for ( TInt index = 0; index < iWidgetList->iRunningWidgets.Count(); index++)
{
SWindowGroupInfo wgInfo = { KWidgetWithoutWG, EFalse };
shownWgIds->AppendL( wgInfo );
}
}
// always shown applications are appended to the end of window group list
for ( TInt index = 0; index < iAlwaysShownList->iAppList->Count(); index++)
{
SWindowGroupInfo wgInfo = { (*iAlwaysShownList->iAppList)[index].iWgId, ETrue };
shownWgIds->AppendL( wgInfo );
}
if ( iIsDisplayed && !iIsClosing && shownWgIds->Count() >= iShownWgIds->Count() )
{
if ( firstAppWgId != KErrNone && firstAppWgId != iFirstAppWgId && firstAppWgId != iBackgroundWgId )
{
CloseFastSwap();
}
}
iFirstAppWgId = firstAppWgId;
if ( iShownWgIds && iShownWgIds->Count() != shownWgIds->Count() )
{
iIsClosing = EFalse;
}
// check if window group of deleted application has been removed
if ( aWaitForWGRemoval && iShownWgIds )
{
// if not removed
if ( shownWgIds->Count() == iShownWgIds->Count() )
{
// no changes are made
TBool needReset = EFalse;
CApaWindowGroupName* appNameInShowList =
CApaWindowGroupName::NewLC(wsSession);
CApaWindowGroupName* appNameInIShowList =
CApaWindowGroupName::NewLC(wsSession);
for ( int i = 0; i < shownWgIds->Count(); i++ )
{
appNameInShowList->ConstructFromWgIdL(shownWgIds->At(i).iWgId);
appNameInIShowList->ConstructFromWgIdL(iShownWgIds->At(i).iWgId);
if ( appNameInShowList->AppUid() != appNameInIShowList->AppUid() )
{
needReset = ETrue;
break;
}
}
CleanupStack::PopAndDestroy(2);
if( !needReset )
{
CleanupStack::PopAndDestroy(shownWgIds);
CleanupStack::PopAndDestroy(); // pop close allWgIds
CleanupStack::PopAndDestroy(allWgIds); // pop delete allWgIds
_AKNTRACE_FUNC_EXIT;
// EFalse if window group list hasn't been changed
return EFalse;
}
}
}
// changes are made
if ( iAllWgIds )
{
iAllWgIds->Close();
}
delete iAllWgIds;
iAllWgIds = allWgIds;
delete iShownWgIds;
iShownWgIds=shownWgIds;
iNumberOfWGs=shownWgIds->Count();
CleanupStack::Pop(shownWgIds);
CleanupStack::Pop(); // pop close allWgIds
CleanupStack::Pop(allWgIds); // pop delete allWgIds
_AKNTRACE_FUNC_EXIT;
// ETrue if window group list has changed
return ETrue;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::VisibleWindowGroupsCountL
// Returns the number of visible window groups found in the system
// ---------------------------------------------------------
//
TInt CAknFastSwapWindowControl::VisibleWindowGroupsCountL()
{
InitializeWindowGroupListL( EFalse );
return iNumberOfWGs;
}
TBool CAknFastSwapWindowControl::IsDisplayed()
{
return iIsDisplayed;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::UpdateGridL
// Modifies grid extent according the parent control rect
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateGridL()
{
_AKNTRACE_FUNC_ENTER;
TAknLayoutRect listScrollLayoutRect;
TAknLayoutRect gridLayoutRect;
listScrollLayoutRect.LayoutRect(
Rect(),
AknLayoutScalable_Avkon::listscroll_fast2_pane( ).LayoutLine() );
// grid
gridLayoutRect.LayoutRect(
listScrollLayoutRect.Rect(),
AknLayoutScalable_Avkon::grid_fast2_pane().LayoutLine() );
TAknLayoutScalableParameterLimits cellLimits = AknLayoutScalable_Avkon::cell_fast2_pane_ParamLimits();
TInt numberOfGridColumns = cellLimits.LastColumn() + 1;
if ( AknLayoutUtils::LayoutMirrored() )
{
iGrid->SetLayoutL(
KVerticalOrientation,
KRightToLeft,
KTopToBottom,
numberOfGridColumns,
NumberOfVisibleRows(),
IconSize() );
}
else
{
iGrid->SetLayoutL(
KVerticalOrientation,
KLeftToRight,
KTopToBottom,
numberOfGridColumns,
NumberOfVisibleRows(),
IconSize() );
}
iGrid->ScrollBarFrame()->SetScrollBarFrameObserver( iGrid );
TRect gridArea = gridLayoutRect.Rect();
if ( iGrid->Rect() != gridArea )
{
iGrid->SetRect( gridArea );
}
AknsUtils::RegisterControlPosition( iGrid );
// scrollbar
AknLayoutUtils::LayoutVerticalScrollBar(
iGrid->ScrollBarFrame(),
listScrollLayoutRect.Rect(),
AknLayoutScalable_Avkon::scroll_pane_cp26().LayoutLine() );
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Updates the UI components.
// ---------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateViewL()
{
_AKNTRACE_FUNC_ENTER;
UpdateItemArraysL();
UpdateGridL();
UpdateControlContext();
iGrid->UpdateScrollBarsL();
UpdateLabelL();
UpdateHeadingIconL();
if ( IsVisible() )
{
DrawDeferred();
}
if ( iIsStylusPopupShow )
{
TPoint pos = PositionRelativeToScreen();
TInt itemIndex = iGrid->CurrentItemIndex();
itemIndex = itemIndex < 0 ? 0 : itemIndex;
TPoint posItem = iGrid->View()->ItemPos( itemIndex );
pos.iY += posItem.iY;
pos.iX += posItem.iX;
if ( AknLayoutUtils::LayoutMirrored() )
{
TInt itemWidth = iGrid->View()->ItemSize( itemIndex ).iWidth;
pos.iX += itemWidth;
}
if ( iPopupMenu )
{
iPopupMenu->SetPosition( pos, CAknStylusPopUpMenu::EPositionTypeLeftBottom );
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::UpdateControlContext
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateControlContext()
{
_AKNTRACE_FUNC_ENTER;
TRect rectParent = Rect();
TAknLayoutRect layoutRect;
layoutRect.LayoutRect(
rectParent,
AknLayoutScalable_Avkon::bg_popup_window_pane_cp17().LayoutLine() );
rectParent = layoutRect.Rect();
layoutRect.LayoutRect(
rectParent,
AknLayoutScalable_Avkon::bg_popup_window_pane_g1(0).LayoutLine() );
iFrameContext->SetFrame(KAknsIIDQsnFrPopup);
iFrameContext->SetFrameRects(rectParent, layoutRect.Rect());
iFrameContext->SetCenter(KAknsIIDQsnFrPopupCenterFswap);
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::Draw
// Symbian OS framework drawing function. Draws the window shadows and
// outline frame.
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::Draw(const TRect& /*aRect*/) const
{
_AKNTRACE_FUNC_ENTER;
if ( iNumberOfWGs < 1 )
{
_AKNTRACE_FUNC_EXIT;
return;
}
CWindowGc& gc = SystemGc();
if( !iTransparencyEnabled )
{
// Should only clear the background when transparency is not enabled
gc.Clear( Rect() );
}
if ( iLowMemIcons )
{
_AKNTRACE_FUNC_EXIT;
return;
}
MAknsSkinInstance *skin = AknsUtils::SkinInstance();
gc.SetPenStyle(CGraphicsContext::ENullPen);
TAknLayoutRect topLeft;
TAknLayoutRect bottomRight;
topLeft.LayoutRect( Rect(), SkinLayout::Popup_windows_skin_placing__frame_general__Line_2());
bottomRight.LayoutRect(Rect(), SkinLayout::Popup_windows_skin_placing__frame_general__Line_5());
TRect innerRect = TRect(topLeft.Rect().iBr, bottomRight.Rect().iTl);
TAknLayoutRect headingArea;
TAknLayoutRect headingBackground;
TAknLayoutRect headingCenter;
TAknLayoutRect iconArea;
headingArea.LayoutRect( Rect(), AknLayoutScalable_Avkon::heading_pane_cp2().LayoutLine() );
headingBackground.LayoutRect( headingArea.Rect(),
AknLayoutScalable_Avkon::bg_popup_heading_pane( 0 ).LayoutLine() );
headingCenter.LayoutRect( headingBackground.Rect(),
AknLayoutScalable_Avkon::bg_popup_heading_pane_g1().LayoutLine() );
if( iTransparencyEnabled )
{
TRegionFix<1> dontDrawRegion;
TRegionFix<8> drawRegion; // 8 should be enough for grid and heading clipping
dontDrawRegion.AddRect( iGrid->Rect() );
drawRegion.AddRect( Rect() );
drawRegion.SubRegion( dontDrawRegion );
gc.SetClippingRegion( drawRegion );
AknsDrawUtils::DrawFrame( skin, gc, Rect(), innerRect,
KAknsIIDQsnFrPopup, KAknsIIDQsnFrPopupCenter); //KAknsIIDQsnFrPopupCenterFswap);
gc.CancelClippingRegion();
}
else
{
AknsDrawUtils::DrawFrame( skin, gc, Rect(), innerRect,
KAknsIIDQsnFrPopup, KAknsIIDQsnFrPopupCenter); //KAknsIIDQsnFrPopupCenterFswap);
}
AknsDrawUtils::DrawFrame( skin, gc, headingBackground.Rect(), headingCenter.Rect(),
KAknsIIDQsnFrPopupHeading, KAknsIIDQsnFrPopupHeadingCenter);
if ( iHeadingIcon )
{
iconArea.LayoutRect(
headingBackground.Rect(),
AknLayoutScalable_Avkon::heading_pane_g2().LayoutLine() );
gc.BitBltMasked( iconArea.Rect().iTl, iHeadingIcon->Bitmap(), iconArea.Rect().Size(),
iHeadingIcon->Mask(), ETrue );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::OfferKeyEventL
// Key handling routine, forwards key events to grid
// ---------------------------------------------------------
//
TKeyResponse CAknFastSwapWindowControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] scancode = %d aType = %d", __FUNCTION__, aKeyEvent.iScanCode, aType );
// if user pressed backspace / clear key the fsw offers
// to close the selected application
if (aType == EEventKey && aKeyEvent.iCode == EKeyBackspace)
{
TBool isShift(EFalse);
#ifdef __WINSCW__
// secret test mode for emulator: shift-backspace sends a definite exit message
isShift = aKeyEvent.iModifiers & (EModifierLeftShift | EModifierRightShift | EModifierShift);
#endif
TryCloseApplicationL(iGrid->CurrentDataIndex(), isShift);
_AKNTRACE_FUNC_EXIT;
return EKeyWasConsumed;
}
if ( AknLayoutUtils::PenEnabled() )
{
if ( aType == EEventKeyUp && aKeyEvent.iScanCode == EStdKeyYes )
{
CloseFastSwap();
_AKNTRACE_FUNC_EXIT;
return EKeyWasNotConsumed ;
}
}
// If user pressed the end key the fastswap will close
if ( aType == EEventKey && ( aKeyEvent.iCode == EKeyNo || aKeyEvent.iCode == EKeyEnd )
|| (aKeyEvent.iCode == EKeyEscape ) )
{
CApaWindowGroupName* wgName = CApaWindowGroupName::NewL( iEikonEnv->WsSession() );
CleanupStack::PushL( wgName );
wgName->ConstructFromWgIdL( iBackgroundWgId );
TBool idleIsBelow = wgName->AppUid() == KIdleAppUid;
CleanupStack::PopAndDestroy( wgName );
// with end key show fullscreen effect but no
// FSW component effect, except if the idle app
// is below FSW
if( !idleIsBelow )
{
GfxTransEffect::BeginFullScreen(5000,
TRect(0,0,0,0),
AknTransEffect::EParameterType,
AknTransEffect::GfxTransParam(
iAppUi.Application()->AppDllUid(),
AknTransEffect::TParameter::EActivateExplicitContinue));
}
if( !idleIsBelow )
{
iDisableFSWEffect = ETrue;
}
CloseFastSwap();
iDisableFSWEffect = EFalse;
_AKNTRACE_FUNC_EXIT;
return EKeyWasConsumed;
}
TInt index = iGrid->CurrentDataIndex();
TKeyResponse keyresponse = iGrid->OfferKeyEventL(aKeyEvent, aType);
if ( index != iGrid->CurrentDataIndex() )
{
UpdateTooltipL();
iTooltip->ShowInfoPopupNote();
}
_AKNTRACE_FUNC_EXIT;
return keyresponse;
}
// ---------------------------------------------------------------------------
// Handles tooltip in touch events and long tapping.
// CAknGrid handles changing the highlighted item and opening the application
// when tapping on a highlighted item.
// ---------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::HandlePointerEventL(
const TPointerEvent& aPointerEvent )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] Type = %d", __FUNCTION__, aPointerEvent.iType );
// FSW does not handle any pointer event when stylus popup
// menu is visible.
if ( iIsStylusPopupShow && aPointerEvent.iType != TPointerEvent::EButton1Up )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( AknLayoutUtils::PenEnabled() )
{
if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
{
PointerEventL( aPointerEvent );
}
// Pointer coordinates start from the top left position of the
// window at the coordinates (0,0).
TRect controlArea( NULL, NULL, iSize.iWidth, iSize.iHeight );
TInt touchedIndex = KErrNotFound;
TBool isOverItem =
iGrid->GridView()->XYPosToItemIndex( aPointerEvent.iPosition,
touchedIndex );
if ( isOverItem )
{
touchedIndex = iGrid->GridView()->ActualDataIndex( touchedIndex );
}
// Cancel touch mode tooltip if pointer is not over an item.
if ( !isOverItem && iTooltipModeTouch )
{
HideTooltip();
iTooltipModeTouch = EFalse;
}
TBool eventInsideControlArea =
controlArea.Contains( aPointerEvent.iPosition );
TBool eventInsideGrid =
iGrid->Rect().Contains( aPointerEvent.iPosition );
TInt oldIndex = iGrid->CurrentDataIndex();
if ( eventInsideControlArea && IsFocused() )
{
// Sends events to the grid and the scrollbar while FSW is focused.
// When tapping a highlight item, the grid sends an
// EEventItemClicked event to FSW, and FSW opens this app.
CCoeControl::HandlePointerEventL( aPointerEvent );
}
else if ( eventInsideControlArea &&
aPointerEvent.iType == TPointerEvent::EButton1Up )
{
// Up event needs to be always passed to the base class so that
// grid's AknPhysics stays in sync.
CCoeControl::HandlePointerEventL( aPointerEvent );
}
switch ( aPointerEvent.iType )
{
case TPointerEvent::EButton1Down:
{
if ( !eventInsideControlArea )
{
// Pointer down was received outside of the FSW.
iStylusDownIn = EFalse;
iIsPointerDownOutOfGrid = EFalse;
}
else
{
// Pointer down was received inside the FSW.
if ( eventInsideGrid )
{
iStylusDownIn = ETrue;
iIsPointerDownOutOfGrid = EFalse;
}
else
{
iStylusDownIn = EFalse;
iIsPointerDownOutOfGrid = ETrue;
}
if ( isOverItem )
{
if ( eventInsideGrid )
{
// Start detecting long tap.
PointerEventL( aPointerEvent );
}
}
}
break;
}
case TPointerEvent::EDrag:
{
if ( !eventInsideControlArea )
{
// Drag event was received outside of the FSW.
if ( iStylusDownIn )
{
// Cancel animation when dragging outside of the FSW.
CancelAnimationAndPressDownEffect();
// Forward the event for scrolling.
CCoeControl::HandlePointerEventL( aPointerEvent );
}
}
else
{
// Drag event was received inside the FSW.
if ( !iStylusDownIn )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( !iItemHighlighted )
{
// Highlight hasn't yet been changed so the item
// index isn't update yet either.
oldIndex = touchedIndex;
}
if ( isOverItem )
{
if ( eventInsideGrid )
{
// Start detecting long tap.
PointerEventL( aPointerEvent );
}
if ( oldIndex != touchedIndex )
{
// Set this in case the listbox hasn't reported
// dragging actioned event in order to not to
// activate item which didn't receive the pointer down.
iItemDraggingActioned = ETrue;
}
}
else if ( iStylusDownIn )
{
CancelAnimationAndPressDownEffect();
}
}
break;
}
case TPointerEvent::EButton1Up:
{
iItemHighlighted = EFalse;
if ( !eventInsideControlArea )
{
// Pointer up was received outside of the FSW.
if ( !iStylusDownIn && !iIsPointerDownOutOfGrid )
{
// The FSW is closed if both the pointer down and
// pointer up events occur outside the window.
CloseFastSwap();
}
CCoeControl::HandlePointerEventL( aPointerEvent );
}
else
{
// Pointer up was received inside the FSW.
if ( !iStylusDownIn )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( isOverItem )
{
// The current item is selected if pointer is
// lifted while in the grid / over a legimate item.
// Cancel touch mode for tooltip.
iTooltipModeTouch = EFalse;
// Open the application as before, but now change the
// highlighted item, so need to update tooltip.
if ( iItemDraggingActioned )
{
if ( iToolTipTimer->IsActive() )
{
iToolTipTimer->Cancel();
}
// Hide tooltip, otherwise tooltip does
// not disappear.
iToolTipTimer->Start(
KTooltipTimeView * 1000,
KTimeNeverHappenEvent,
TCallBack( ToolTipTimeOutCallBackL, this ) );
}
}
}
break;
}
default:
{
CCoeControl::HandlePointerEventL( aPointerEvent );
break;
}
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::ProcessCommandL
// Softkey event handling
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::ProcessCommandL(TInt aCommandId)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aCommandId = %d", __FUNCTION__, aCommandId );
switch (aCommandId)
{
case EAknSoftkeyCancel:
SwitchToTask( iBackgroundWgId );
break;
case EAknSoftkeySelect:
HandleListBoxEventL( iGrid, EEventEnterKeyPressed );
break;
case EAknCapServerCmdOpen:
SetHiddenFlag();
SwitchToApplicationL( iGrid->CurrentDataIndex() );
break;
case EAknCapServerCmdClose:
SetHiddenFlag();
TryCloseApplicationL( iGrid->CurrentDataIndex() );
break;
case KErrCancel:
SetHiddenFlag();
break;
default:
_AKNTRACE_FUNC_EXIT;
return;
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Handles item selection in the grid.
// ---------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::HandleListBoxEventL( CEikListBox* /*aListBox*/,
TListBoxEvent aEventType )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aEventType = %d", __FUNCTION__, aEventType );
switch ( aEventType )
{
case MEikListBoxObserver::EEventPenDownOnItem:
iItemDraggingActioned = EFalse;
iPressDownTime.HomeTime();
break;
case MEikListBoxObserver::EEventEnterKeyPressed:
SwitchToApplicationL( iGrid->CurrentDataIndex() );
break;
case MEikListBoxObserver::EEventItemClicked:
case MEikListBoxObserver::EEventItemSingleClicked:
if ( !iItemDraggingActioned && !iIsStylusPopupShow )
{
TTime now;
now.HomeTime();
TInt64 diffTime = KPressedDownEffectTime - now.MicroSecondsFrom(iPressDownTime).Int64();
if( diffTime > 0 )
{
// wait for the diffTime
User::After( diffTime );
}
SwitchToApplicationL( iGrid->CurrentDataIndex() );
}
break;
case MEikListBoxObserver::EEventPanningStarted:
case MEikListBoxObserver::EEventFlickStarted:
case MEikListBoxObserver::EEventItemDraggingActioned:
HideTooltip();
CancelAnimationAndPressDownEffect();
break;
default:
break;
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Handles events from grid
// ---------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::HandleControlEventL(
CCoeControl *aControl, TCoeEvent aEventType )
{
_AKNTRACE_FUNC_ENTER;
if ( aControl == iGrid && aEventType == EEventStateChanged && iIsDisplayed )
{
iItemHighlighted = ETrue;
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::FadeBackground
// Fades the underlying window group when fastswap is invoked
// ( if not already faded)
// implementation is similar to Eikon dialogs
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::FadeBackground(TBool aFade)
{
AknGlobalPopupPriorityController::FadeBehindPopup(*this, iPopupFader, *this, aFade);
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateGridL
// Grid construction
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateGridL()
{
_AKNTRACE_FUNC_ENTER;
ASSERT(!iGrid);
TAknLayoutScalableParameterLimits cellLimits = AknLayoutScalable_Avkon::cell_fast2_pane_ParamLimits();
TInt numberOfGridColumns = cellLimits.LastColumn() + 1;
iGrid = new (ELeave) CAknFastSwapWindowGrid;
iGrid->ConstructL( this, EAknListBoxSelectionGrid | EAknListBoxScrollBarSizeExcluded );
iGrid->SetLayoutL( KVerticalOrientation, KLeftToRight,
KTopToBottom, numberOfGridColumns, NumberOfVisibleRows(), IconSize() );
iGrid->SetObserver( this );
// CAknGrid creates a window owning scroll bar. This causes flickering of
// the scroll bar when fast swap window is opened. Create a non window
// owning scroll bar and install it into the grid.
CEikScrollBarFrame* sbFrame = new(ELeave) CEikScrollBarFrame(
this, iGrid, ETrue);
CleanupStack::PushL(sbFrame);
if (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan)
{
sbFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue, EFalse);
}
iGrid->SetScrollBarFrame(sbFrame, CEikListBox::ENotOwnedExternally);
CleanupStack::Pop(); // sbFrame
iGrid->SetPrimaryScrollingType( KHorizontalScrollingType );
iGrid->SetSecondaryScrollingType( KVerticalScrollingType );
iGrid->SetCurrentDataIndex( 0 );
iGrid->SetRect( TRect( 0, 0, 10, 10 ) ); // avoids grid panic
iGrid->SetContainerWindowL(*this);
iGrid->SetListBoxObserver(this);
// Scroll bar should be shown always when fsw visible
iGrid->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,
CEikScrollBarFrame::EAuto);
if (iTransparencyEnabled)
{
// When fast swap window opens, scroll bar background appears to be
// drawn twice during transition even if it is added into a clipping
// region in CAknFastSwapWindowControl::Draw(). Therefore background
// drawing is disabled in scroll bar and drawn by this control.
iGrid->ScrollBarFrame()->DrawBackground(EFalse, EFalse);
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateGridL
// Creates CCoeControlArray for the child controls
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateComponentArrayL()
{
_AKNTRACE_FUNC_ENTER;
InitComponentArrayL();
Components().AppendLC( iGrid, 0 );
CleanupStack::Pop();
Components().AppendLC( iLabel, 1 );
CleanupStack::Pop();
CEikScrollBar* scrollBar = iGrid->ScrollBarFrame()->VerticalScrollBar();
if (scrollBar)
{
Components().AppendLC(scrollBar, 2);
CleanupStack::Pop();
}
Components().SetControlsOwnedExternally( ETrue );
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateTooltipL
//
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateTooltipL()
{
_AKNTRACE_FUNC_ENTER;
iTooltip = CAknInfoPopupNoteController::NewL();
iTooltip->SetTimeDelayBeforeShow( KTooltipTimeBefore );
iTooltip->SetTimePopupInView( KTooltipTimeView );
iTooltip->SetTooltipModeL( ETrue );
iTooltip->HideWhenAppFaded( EFalse );
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateLabelL
// Creates tooltip that shows application name of highlighted application icon
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateLabelL()
{
_AKNTRACE_FUNC_ENTER;
// read label from resources qtn_options_task_swapper
HBufC* labelBuffer = CCoeEnv::Static()->AllocReadResourceL( R_QTN_SELEC_TITLE_SWAPPER );
CleanupStack::PushL( labelBuffer );
// determine the width of the text
// determining the size of the text
TAknLayoutRect headingRect;
headingRect.LayoutRect( FastSwapWindowRect(),
AknLayoutScalable_Avkon::heading_pane( 0 ).LayoutLine());
TAknLayoutText textLayout;
textLayout.LayoutText( headingRect.Rect(),
AknLayoutScalable_Avkon::heading_pane_t1( 2 ).LayoutLine() );
TInt width = textLayout.TextRect().Width();
// clip the label
TPtr clippedStringPtr = labelBuffer->Des();
AknBidiTextUtils::ConvertToVisualAndClipL(
clippedStringPtr, *textLayout.Font() /**iEikonEnv->NormalFont()*/, width, width );
// create label
iLabel = new (ELeave) CEikLabel();
iLabel->SetContainerWindowL( *this );
iLabel->SetTextL( *labelBuffer );
iLabel->UseLogicalToVisualConversion( EFalse );
iLabel->SetBrushStyle( CGraphicsContext::ENullBrush );
CleanupStack::PopAndDestroy(); // labelBuffer
_AKNTRACE_FUNC_EXIT;
}
void CAknFastSwapWindowControl::UpdateLabelL()
{
_AKNTRACE_FUNC_ENTER;
// layout
TAknLayoutRect headingArea;
TAknLayoutRect textArea;
headingArea.LayoutRect( Rect(), AknLayoutScalable_Avkon::heading_pane_cp2().LayoutLine());
AknLayoutUtils::LayoutLabel(
iLabel,
headingArea.Rect(),
AknLayoutScalable_Avkon::heading_pane_t1( 2 ).LayoutLine(),
iEikonEnv->NormalFont());
// skin
TRgb color;
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
TInt error = AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnTextColors,
EAknsCIQsnTextColorsCG19 );
if (!error)
{
// Ignore error
TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( *iLabel, EColorLabelText, color ) );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateGridL
// Updates tooltip with right application name andthat shows application name of highlighted
// application icon
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateTooltipL()
{
_AKNTRACE_FUNC_ENTER;
iTooltip->HideInfoPopupNote();
if ( !IsFocused() || IsDimmed() || iGrid->CurrentDataIndex() == KErrNotFound )
{
_AKNTRACE_FUNC_EXIT;
return;
}
TRect currentItemRect = CurrentGridItemRect();
if ( currentItemRect.iTl.iY < iGrid->View()->ViewRect().iTl.iY )
{
currentItemRect.iTl.iY = iGrid->View()->ViewRect().iTl.iY;
}
TAknLayoutRect rect;
TRect parent;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, parent );
currentItemRect.Move( FastSwapWindowRect().iTl );
// The tooltip width must be set before calculating the floating point in
// SetPositionAndAlignment().
iTooltip->SetTextL( CurrentAppName() );
iTooltip->SetPositionByHighlight(currentItemRect); // This method also checks the current layout (European or Arabic)
if( !iTooltipModeTouch )
{
iTooltip->SetTimeDelayBeforeShow(KTooltipTimeBefore);
iTooltip->SetTimePopupInView(KTooltipTimeView);
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::ShowTooltipTouchL
// Handles tooltip when touch input is used.
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::ShowTooltipTouchL(TBool aPointerOverItem)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aPointerOverItem = %d", __FUNCTION__, aPointerOverItem );
if( !iTooltipModeTouch && aPointerOverItem)
{
iTooltip->SetTimeDelayBeforeShow(KTooltipTimeBeforeTouch);
iTooltip->SetTimePopupInView(KTooltipTimeViewTouch);
iTooltipModeTouch = ETrue;
}
// Show tooltip only when fast swap control has keyboard focus.
if (IsFocused())
{
UpdateTooltipL();
iTooltip->ShowInfoPopupNote();
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CurrentGridItemRect
// The rect of current highlighted grid item
// ---------------------------------------------------------
//
TRect CAknFastSwapWindowControl::CurrentGridItemRect()
{
_AKNTRACE_FUNC_ENTER;
// must be item index, not data index as usual
TInt index = iGrid->CurrentItemIndex();
if( index != KErrNotFound )
{
TRect currentItemRect = TRect( iGrid->View()->ItemPos( index ) /*item pos*/,
iGrid->View()->ItemSize( 0) /*item size*/);
_AKNTRACE_FUNC_EXIT;
return currentItemRect;
}
_AKNTRACE_FUNC_EXIT;
return TRect( NULL, NULL, NULL, NULL );
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::UpdateHeadingIconL
// Resets heading icon with the icon provided by the current skin
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateHeadingIconL()
{
_AKNTRACE_FUNC_ENTER;
if ( iLowMemory )
{
_AKNTRACE_FUNC_EXIT;
return;
}
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
CGulIcon* headingIcon = AknsUtils::CreateGulIconL(
skin, KAknsIIDQgnIndiAppOpen,
AknIconUtils::AvkonIconFileName(),
EMbmAvkonQgn_indi_app_open_add,
EMbmAvkonQgn_indi_app_open_add_mask);
CleanupStack::PushL( headingIcon ); // to stack
TAknLayoutRect headingArea;
TAknLayoutRect headingBackground;
TAknLayoutRect iconArea;
headingArea.LayoutRect( Rect(), AknLayoutScalable_Avkon::heading_pane_cp2().LayoutLine() );
headingBackground.LayoutRect(
headingArea.Rect(),
AknLayoutScalable_Avkon::bg_popup_heading_pane( 0 ).LayoutLine() );
iconArea.LayoutRect(
headingBackground.Rect(),
AknLayoutScalable_Avkon::heading_pane_g2().LayoutLine() );
User::LeaveIfError( AknIconUtils::SetSize( headingIcon->Bitmap(), iconArea.Rect().Size() ) );
delete iHeadingIcon;
iHeadingIcon = headingIcon;
CleanupStack::Pop(); // headingIcon
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateCbaL
// Softkey construction (component control of CAknFastswapWindowControl)
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateCbaL()
{
_AKNTRACE_FUNC_ENTER;
ASSERT(!iCba);
TRect screenRect;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
iCba = CEikButtonGroupContainer::NewL(
CEikButtonGroupContainer::ECba,
CEikButtonGroupContainer::EHorizontal,
this, R_AVKON_SOFTKEYS_SELECT_CANCEL__SELECT);
iCba->MakeVisible( EFalse );
iCba->SetBoundingRect( screenRect );
iCba->ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( -1 ); // -1 puts this window at the back
iAppUi.RemoveFromStack( iCba->ButtonGroup()->AsControl() );
AknGlobalPopupPriorityController::AddSubPopupL(*this, *iCba->ButtonGroup()->AsControl());
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::UpdateItemArraysL
// Retrieves the application names and icons via the apparc
// server, and stores them in arrays.
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateItemArraysL()
{
_AKNTRACE_FUNC_ENTER;
ClearItemArrays( EFalse );
RWsSession& wsSession = iEikonEnv->WsSession();
TBuf<2*KMaxFileName+1> name;
// Set the icon size we wish retrieve
TUid appUid;
TInt wgId;
for (TInt index=0; index<iNumberOfWGs; index++)
{
wgId=(*iShownWgIds)[index].iWgId;
TApaAppInfo info;
//
// Always shown applications
//
if ( iAlwaysShownList->IsAlwaysShownApp( wgId ) )
{
appUid = iAlwaysShownList->IndexToAppUid( index );
iAppArcSession.GetAppInfo( info, appUid );
// retrieve the app name
TPtrC caption = info.iShortCaption;
name.Zero();
// conversion from TInt to TReal, might be a problem in the future
name.AppendNum( index );
name.Append( KTab );
name.Append( caption );
}
else if (iWidgetsSupported && iWidgetList->IsWidget( wgId ))
{
appUid = iWidgetList->IndexToAppUid( index, iAlwaysShownList->iAppList->Count() );
iAppArcSession.GetAppInfo( info, appUid );
// retrieve the app name
TPtrC caption = info.iShortCaption;
name.Zero();
// conversion from TInt to TReal, might be a problem in the future
name.AppendNum( index );
name.Append( KTab );
name.Append( caption );
}
//
// Running Applications
//
else
{
CApaWindowGroupName* windowName = CApaWindowGroupName::NewLC( wsSession, wgId );
appUid = windowName->AppUid();
iAppArcSession.GetAppInfo( info, appUid );
//Retrieve the app name
TPtrC caption = info.iShortCaption;
name.Zero();
// conversion from TInt to TReal, might be a problem in the future
name.AppendNum( index );
name.Append( KTab );
if ( !( caption.Length() ) ) // if not set - use thread name instead
{
if (windowName->Caption().Length() != 0)
{
name.Append( windowName->Caption() );
}
else
{
TThreadId threadId;
TInt err = wsSession.GetWindowGroupClientThreadId( wgId, threadId );
if ( err == KErrNone )
{
RThread thread;
err = thread.Open( threadId);
if ( err==KErrNone )
{
name.Append( thread.Name() );
thread.Close();
}
}
}
}
else
{
name.Append( caption );
}
CleanupStack::PopAndDestroy(); //windowName
}
// we discontinue if no more items can be added to the icon array
TBool iconAddSuccess = ETrue;
TRAPD(error ,iconAddSuccess = AddIconToArrayL( appUid ));
if (!iconAddSuccess)
{
break;
}
if( error != KErrNone )
{
if( error == KErrNoMemory )
{
User::LeaveNoMemory();
}
if( error == KErrNotFound )
{
iIconArray->AppendL( iDefaultAppIcon);
}
else
{
User::Leave(error);
}
}
iItemTextArray->AppendL( name );
}
// update the grid according the changes made to icon arrays
TInt newCount = iItemTextArray->MdcaCount();
if (newCount >= iOldCount)
iGrid->HandleItemAdditionL();
else
{
iGrid->HandleItemRemovalL();
if ( ( iGrid->Model()->NumberOfItems() % iGrid->GridView()->NumberOfColsInView() ) == 0 )
{
TInt logicalRow;
TInt logicalColumn;
TInt topItemIndex;
iGrid->GridView()->LogicalPosFromListBoxIndex(
iGrid->TopItemIndex(),
logicalRow,
logicalColumn );
logicalRow = Max( 0, logicalRow - 1 );
iGrid->GridView()->ListBoxIndexFromLogicalPos(
topItemIndex,
logicalRow,
logicalColumn );
iGrid->SetTopItemIndex( topItemIndex );
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::AddIconToArrayL
// Application is added to the AknGrid icon array
// if it can be found and if there is enough memory
// If not, default application icon is used
// ---------------------------------------------------------
//
TBool CAknFastSwapWindowControl::AddIconToArrayL( TUid aAppUid )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aAppUid = %d", __FUNCTION__, aAppUid.iUid );
if ( iLowMemory )
{
// when memory is low, only one prereserved
// default app icon is used for every grid item
TRAPD( err, iIconArray->AppendL( iDefaultAppIcon) );
if ( err != KErrNone )
{
_AKNTRACE_FUNC_EXIT;
// if memory runs out, FSW uses what it has
// and continues (should never happen)
return EFalse;
}
iLowMemIcons = ETrue;
// fsw can only quarantee KMinimumSupportedApps number of apps
// in low memory conditions, so after KMinimumSupportedApps items
// no more items are added to the memory
if ( iItemTextArray->Count() >= KMinimumSupportedApps )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
}
else
{
CGulIcon* icon;
CFbsBitmap* bitmap;
CFbsBitmap* mask;
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
// Retrieve the app icon using the Uid
AknsUtils::CreateAppIconLC( skin, aAppUid, EAknsAppIconTypeList,bitmap, mask );
User::LeaveIfError( AknIconUtils::SetSize( bitmap, IconSize() ) );
icon = CGulIcon::NewL( bitmap, mask ); //takes ownership
CleanupStack::PushL( icon );
CleanupStack::Pop( 2 ); // bitmap, mask
iIconArray->AppendL( icon ); //takes ownership
CleanupStack::Pop(); // icon
}
_AKNTRACE_FUNC_EXIT;
return ETrue;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::SwitchToApplicationL
// Either launches an application using method LaunchAppL
// or brings existing task to foreground by calling method SwitchToTask
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::SwitchToApplicationL( TInt aIndex )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aIndex = %d", __FUNCTION__, aIndex );
// abort FSW transition when item chosen (case when choosing quickly)
GfxTransEffect::Abort();
TInt wgId = (*iShownWgIds)[ aIndex ].iWgId;
// launches application and closes fastswap
if ( wgId == KApplicationWithoutWG )
{
LaunchAppL( iAlwaysShownList->IndexToAppUid( aIndex ) );
}
else if ( iWidgetsSupported && wgId == KWidgetWithoutWG )
{
LaunchAppL( iWidgetList->IndexToAppUid( aIndex, iAlwaysShownList->iAppList->Count() ) );
}
// brings existing application to foreground and closes fastswap
else
{
if ( iAlwaysShownList->IsAlwaysShownApp( wgId ) &&
iAlwaysShownList->IndexToAppUid( aIndex ) == KMenuAppUid )
{
TBuf<128> viewType;
if ( wgId != iBackgroundWgId ||
( RProperty::Get(KFSWMMenuPSCat, KFSWMMenuLastViewKey, viewType) == KErrNone &&
viewType.Compare(KFSWMMenuFolderView) != 0 ) )
{
TApaTask task( iEikonEnv->WsSession() );
task.SetWgId( wgId );
task.SendMessage(KUidApaMessageSwitchOpenFile, KNullDesC8);
}
}
SwitchToTask( wgId );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::SwitchToTask
// Brings a task associated with the given window group to
// the foreground, and dismissed CAknFastswapWindowControl
// from the screen and removes it from the control stack
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::SwitchToTask( TInt aWgId )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aWgId = %d", __FUNCTION__, aWgId );
CloseFastSwap();
if( iFirstAppWgId != aWgId && iBackgroundWgId != aWgId )
{
GfxTransEffect::BeginFullScreen(5000,
TRect(0,0,0,0),
AknTransEffect::EParameterType,
AknTransEffect::GfxTransParam(
iAppUi.Application()->AppDllUid(),
AknTransEffect::TParameter::EActivateExplicitContinue));
}
CAknSgcClient::MoveApp(aWgId, ESgcMoveAppToForeground);
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::SwitchToTask
// Launches an application to the phone memory based on the
// given application uid and closes the fastswap
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::LaunchAppL( TUid aAppUid )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aAppUid = %d", __FUNCTION__, aAppUid.iUid );
RApaLsSession ls;
User::LeaveIfError(ls.Connect());
CleanupClosePushL(ls);
CApaCommandLine* cmdLine=CApaCommandLine::NewLC();
cmdLine->SetCommandL(EApaCommandRun);
TApaAppInfo info;
iAppArcSession.GetAppInfo( info, aAppUid );
cmdLine->SetExecutableNameL( info.iFullName );
ls.StartApp( *cmdLine );
CleanupStack::PopAndDestroy(2); // cmdLine, ls
// informing the system about a transition
CloseFastSwap();
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CloseFastSwap
// Dismisses CAknFastswapWindowControl
// from the screen and removes it from the control stack
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CloseFastSwap()
{
_AKNTRACE_FUNC_ENTER;
if ( iIsDisplayed )
{
TInt effectValue( 0 );
iThemesAppRepository->Get( KThemesTransitionEffects, effectValue );
if ( effectValue == 0 ) /* TAT on */
{
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
feedback->InstantFeedback( ETouchFeedbackDecreasingPopUp );
}
}
// calculate already here since PositionRelativeToScreen
// causes a flush to WS, which can disturb transition
TPoint dPoint( iGrid->PositionRelativeToScreen() );
TRect dRect( iGrid->Rect() );
dRect.Move( dPoint );
TBool visible = IsVisible();
TBool rsWasEnabled( EFalse );
if( !iDisableFSWEffect )
{
if( !iTransparencyEnabled && Window().IsRedrawStoreEnabled() )
{
rsWasEnabled = ETrue;
// disable rsStore during transition
Window().EnableRedrawStore( EFalse );
}
// If we never got to the callback after the appear effect, we
// remove the observer here, so that we don't get the callback
// when the disappear effect finishes.
CAknFastSwapData *data =
(CAknFastSwapData*)CAknTransitionUtils::GetData( (TInt)this );
CAknTransitionUtils::RemoveObserver( data,
CAknTransitionUtils::EEventControlTransitionFinished );
if(visible)
{
GfxTransEffect::Begin( this, KGfxControlDisappearAction );
GfxTransEffect::NotifyExternalState(ECaptureComponentsBegin, (const TDesC8*)this);
}
}
delete iConfirmCloseDialog;
iConfirmCloseDialog = NULL;
iTooltip->HideInfoPopupNote();
if ( iTimeOut->IsActive() )
{
iTimeOut->Cancel();
StopAnimation();
iState = EWaiting;
iTooltipModeTouch = EFalse;
}
if ( iIsStylusPopupShow )
{
//for Hide popup menu,but CStylusPopupMenu does not export HideMenu method.
delete iPopupMenu;
iPopupMenu = NULL;
SetHiddenFlag();
}
MakeVisible( EFalse );
if( !iDisableFSWEffect )
{
if(visible)
{
CAknTransitionUtils::MakeVisibleSubComponents( this,
CAknTransitionUtils::EForceInvisible );
GfxTransEffect::SetDemarcation( this, dRect );
GfxTransEffect::NotifyExternalState(ECaptureComponentsEnd, (const TDesC8*)this);
GfxTransEffect::End( this );
}
if( !iTransparencyEnabled && rsWasEnabled )
{
Window().EnableRedrawStore( ETrue );
}
}
GfxTransEffect::Deregister( this );
FadeBackground( EFalse );
AknGlobalPopupPriorityController::ShowPopup(*this, EFalse);
InvalidateWindows(this);
iCba->MakeVisible( EFalse );
SetFocus( EFalse );
iAppUi.RemoveFromStack( iCba->ButtonGroup()->AsControl() );
iAppUi.RemoveFromStack( this );
SetPointerCapture( EFalse );
//IgnoreEventsUntilNextPointerUp();
// Item array data like app names and icons
// is not preserved when the FSW is not visible
// (to save used heap)
ClearItemArrays( ETrue );
}
iIsDisplayed = EFalse;
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CleanupRunFastSwap
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CleanupRunFastSwap(TAny* aThis)
{
( (CAknFastSwapWindowControl*) aThis)->CloseFastSwap();
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::HandleShortAppsKeyPressL
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::HandleShortAppsKeyPressL()
{
_AKNTRACE_FUNC_ENTER;
if ( !iConfirmCloseDialog && IsFocused() )
{
TInt index = ( iGrid->CurrentDataIndex() + 1) % iShownWgIds->Count();
iGrid->SetCurrentDataIndex( index );
iGrid->DrawDeferred();
UpdateTooltipL();
iTooltip->ShowInfoPopupNote();
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::HandleLongAppsKeyPressL
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::HandleLongAppsKeyPressL()
{
_AKNTRACE_FUNC_ENTER;
if (!iConfirmCloseDialog)
{
HandleListBoxEventL( iGrid, EEventEnterKeyPressed );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::MopSupplyObject
// ---------------------------------------------------------
//
TTypeUid::Ptr CAknFastSwapWindowControl::MopSupplyObject(TTypeUid aId)
{
if ( aId.iUid == MAknsControlContext::ETypeId )
{
return ( MAknsControlContext::SupplyMopObject( aId, iFrameContext ) ) ;
}
return SupplyMopObject(aId, iCba);
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::FastSwapWindowRect
// ---------------------------------------------------------
//
TRect CAknFastSwapWindowControl::FastSwapWindowRect()
{
_AKNTRACE_FUNC_ENTER;
TRect parent;
TAknLayoutRect rect;
TRect finalRect;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, parent );
AknLayoutUtils::TAknCbaLocation cbaLocation( AknLayoutUtils::CbaLocation() );
TInt variety( 0 );
if ( cbaLocation == AknLayoutUtils::EAknCbaLocationRight )
{
variety = 3;
}
else if ( cbaLocation == AknLayoutUtils::EAknCbaLocationLeft )
{
variety = 6;
}
else
{
variety = 0;
}
if( Layout_Meta_Data::IsLandscapeOrientation() &&
Layout_Meta_Data::IsPenEnabled() &&
cbaLocation == AknLayoutUtils::EAknCbaLocationBottom &&
!AknStatuspaneUtils::FlatLayoutActive() )
{
variety = 3;
}
rect.LayoutRect( parent,
AknLayoutScalable_Avkon::popup_fast_swap2_window(
variety + NumberOfVisibleRows() - 1 ).LayoutLine() );
_AKNTRACE_FUNC_EXIT;
return rect.Rect();
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CountFadedComponents
// ---------------------------------------------------------
//
TInt CAknFastSwapWindowControl::CountFadedComponents()
{
return 4;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::FadedComponent
// ---------------------------------------------------------
//
CCoeControl* CAknFastSwapWindowControl::FadedComponent(TInt aIndex)
{
_AKNTRACE( "[%s] aIndex = %d", __FUNCTION__, aIndex );
switch (aIndex)
{
case 0:
return this;
case 1:
return iGrid;
case 2:
return iCba;
case 3:
return iLongTapAnimation;
default:
return NULL;
}
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::OfferCloseSelectedAppL
// ---------------------------------------------------------
//
TBool CAknFastSwapWindowControl::OfferCloseSelectedAppL(const TDesC& aName)
{
_AKNTRACE_FUNC_ENTER;
HBufC* msg = StringLoader::LoadLC(R_CONFIRM_CLOSE_APP_MESSAGE, aName, iEikonEnv);
delete iConfirmCloseDialog;
iConfirmCloseDialog = NULL;
iConfirmCloseDialog = CAknQueryDialog::NewL( CAknQueryDialog::EConfirmationTone );
iConfirmCloseDialog->SetPromptL( *msg );
CleanupStack::PopAndDestroy(msg);
TBool ok = iConfirmCloseDialog->ExecuteLD(R_CONFIRM_CLOSE_APP_QUERY);
iConfirmCloseDialog = NULL;
_AKNTRACE_FUNC_EXIT;
return ok;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::IsWgIdInShownList
// ---------------------------------------------------------
//
TBool CAknFastSwapWindowControl::IsWgIdInShownList(TInt aWgId)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aWgId = %d", __FUNCTION__, aWgId );
TInt count = iShownWgIds->Count();
for (TInt ii=0; ii<count; ii++)
{
if ( iShownWgIds->At(ii).iWgId == aWgId )
{
_AKNTRACE_FUNC_EXIT;
return ETrue;
}
}
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::FocusChanged
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::FocusChanged(TDrawNow /*aDrawNow*/)
{
_AKNTRACE_FUNC_ENTER;
if( iGrid )
{
iGrid->SetFocus( IsFocused() );
}
if (!IsFocused() && iTooltip)
{
iTooltip->HideInfoPopupNote();
}
if ( !IsFocused() && iIsStylusPopupShow )
{
delete iPopupMenu;
iPopupMenu = NULL;
SetHiddenFlag();
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::SizeChanged
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::SizeChanged()
{
_AKNTRACE_FUNC_ENTER;
// FSW tries to update the UI
TRAPD( err, UpdateViewL() );
// if the creation of the grid wasn't successful,
// FSW creates a grid without reserving new icons
if ( err != KErrNone )
{
if ( err == KErrNoMemory )
{
// FSW in low memory
iLowMemory = ETrue;
TRAP_IGNORE( UpdateViewL() );
iLowMemory = EFalse;
// above should always work, because memory is always
// reserved for default application icon and the minimum of 20 apps
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::HandleResourceChange
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::HandleResourceChange(TInt aType)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aType = %d", __FUNCTION__, aType );
CCoeControl::HandleResourceChange(aType);
if ( aType == KAknsMessageSkinChange )
{
TRAP_IGNORE( UpdateDefaultAppIconL() );
}
if ( iCba )
{
iCba->HandleResourceChange(aType);
}
if(iGrid && iGrid->ScrollBarFrame() && iGrid->ScrollBarFrame()->VerticalScrollBar())
{
iGrid->ScrollBarFrame()->VerticalScrollBar()->HandleResourceChange(aType);
}
if ( aType == KEikDynamicLayoutVariantSwitch )
{
SetRect( FastSwapWindowRect() );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CreateItemArraysL
// During the creation of the grid the used item arrays
// are also created and set in to the grid. Arrays reserve
// memory so that fsw can be quaranteed to work also in
// low memory conditions.
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateItemArraysL()
{
_AKNTRACE_FUNC_ENTER;
// fetch default application icon from the skin
UpdateDefaultAppIconL();
// FSW reserves memory for icon and item arrays
iIconArray = new (ELeave) CArrayPtrFlat<CGulIcon>(KFSWArrayGranularity);
iItemTextArray = new (ELeave) CDesCArrayFlat(KFSWArrayGranularity);
iIconArray->SetReserveL( KMinimumSupportedApps );
TBuf<2*KMaxFileName+1> name;
for ( TInt count = 0; count < KMinimumSupportedApps; count ++)
{
iItemTextArray->AppendL( name );
}
iItemTextArray->Delete( NULL, iItemTextArray->Count() );
// without setting this null the automatically created itemtextarray
// wont be freed
iGrid->Model()->SetItemTextArray( NULL );
// grid doesn't take ownership of the arrays
iGrid->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
// arrays are set into grid
iGrid->Model()->SetItemTextArray( iItemTextArray );
iGrid->ItemDrawer()->FormattedCellData()->SetIconArrayL( iIconArray );
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::SetDefaultAppIconL
// Retrieves the default application icon from the skin,
// icon is to be used when there is no memory to reserve new icons
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::UpdateDefaultAppIconL()
{
_AKNTRACE_FUNC_ENTER;
CGulIcon* defaultAppIcon = NULL;
TRAPD( error,defaultAppIcon = AknsUtils::CreateGulIconL(
AknsUtils::SkinInstance(),
KAknsIIDQgnMenuUnknownCxt,
AknIconUtils::AvkonIconFileName(),
EMbmAvkonQgn_menu_unknown_cxt,
EMbmAvkonQgn_menu_unknown_cxt_mask ) );
CleanupStack::PushL( defaultAppIcon );
if ( error != KErrNone )
{
if ( error == KErrNoMemory )
{
_AKNTRACE_FUNC_EXIT;
return;
}
else
{
User::LeaveIfError(error);
}
}
User::LeaveIfError( AknIconUtils::SetSize(
defaultAppIcon->Bitmap(),
IconSize() ) );
if ( iIconArray != NULL && iIconArray->Count() > 0)
{
for ( TInt i = 0; i < iIconArray->Count(); i++ )
{
if( iDefaultAppIcon == iIconArray->At(i) )
{
iIconArray->At(i) = defaultAppIcon;
}
}
}
delete iDefaultAppIcon;
iDefaultAppIcon = defaultAppIcon;
CleanupStack::Pop(); // defaultAppIcon
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::ClearItemArrays
// The content is deleted from arrays and arrays can be compressed
// to the reserved size KMinimumSupportedApps
//
// TBool aCompress states whether the arrays are are to be compressed or not
//
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::ClearItemArrays( TBool aCompress )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aCompress = %d", __FUNCTION__, aCompress );
// Old count is used comparison later when new items are added to array
// if handling of the item addition / removal is needed for the fsw grid
if ( !iIconArray )
{
_AKNTRACE_FUNC_EXIT;
return;
}
TInt currentlyReserved = iIconArray->Count();
if ( currentlyReserved > NULL )
{
// compression for arrays is done when the closefastswap is called
// when the fsw is updated while visible compression is not very wise
// since the item arrays are probably very close to the
if ( aCompress )
{
// if there have been two many applications running lets
// try to compress the arrays to size of KMinimumSupportedApps
if ( iItemTextArray->Count() > KMinimumSupportedApps )
{
iItemTextArray->Delete(
KMinimumSupportedApps,
iItemTextArray->Count() - KMinimumSupportedApps);
iItemTextArray->Compress();
}
// arrays are deleted separately, since there exists situations
// when memory allocation has failed and arrays have different
// number of cells
if ( currentlyReserved > KMinimumSupportedApps )
{
if ( iLowMemIcons )
{
// resizes to KMinimumSupportedApps, no dynamically loaded icons,
// every pointer in the icon array points to the same default app icon
// (never deleted)
iIconArray->Delete(
KMinimumSupportedApps,
currentlyReserved - KMinimumSupportedApps );
}
else
{
// deletes dynamically loaded icons
DeleteIcons(
KMinimumSupportedApps,
currentlyReserved - KMinimumSupportedApps );
}
// compresses the array to max KMinimumSupportedApps
iIconArray->Compress();
TRAP_IGNORE( iGrid->HandleItemRemovalL() );
}
}
// if arrays are emptified, fsw needs information
// how many apps were in the grid before the operation
iOldCount = iGrid->Model()->ItemTextArray()->MdcaCount();
// the deletion doesn't free the memory reserved for the array,
// but it emptifies the text array
iItemTextArray->Delete( NULL, iItemTextArray->Count() );
// if the memory was too low
// on the previously run, different icon array
// was used, and also needs to be freed differentely
if ( iLowMemIcons )
{
// resizing doesn't free the memory
// array or the used icon reserved
//
// below resize can leave when array is enlarged,
// but in this case size always shrunk to NULL
TRAP_IGNORE( iIconArray->Delete( NULL, iIconArray->Count() ) );
iLowMemIcons = EFalse;
}
else
{
// icons inside array are deleted from the memory,
// but the deletion doesn't free the memory
// reserved for the pointer array
DeleteIcons( NULL, iIconArray->Count() );
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::IconSize
// Calculates and returns the icon size used in the fast swap list.
// ---------------------------------------------------------
//
TSize CAknFastSwapWindowControl::IconSize()
{
_AKNTRACE_FUNC_ENTER;
TRect appWindow;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow, appWindow );
TAknLayoutRect rect;
rect.LayoutRect(
FastSwapWindowRect(),
AknLayoutScalable_Avkon::aid_size_cell_fast2().LayoutLine());
_AKNTRACE_FUNC_EXIT;
return rect.Rect().Size();
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::DeleteIcons
// Clears given array slots of dynamically loaded icons
// ---------------------------------------------------------
//
void CAknFastSwapWindowControl::DeleteIcons( TInt aIndex, TInt aCount )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aIndex = %d aCount = %d", __FUNCTION__, aIndex, aCount );
for ( TInt i = 0; i < aCount; i++ )
{
if(iDefaultAppIcon != iIconArray->At( aIndex + i ))
{
delete iIconArray->At( aIndex + i );
}
}
iIconArray->Delete( aIndex, aCount );
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::NumberOfVisibleRows
// How many visible rows are shown in the fast swap grid
// ---------------------------------------------------------
//
TInt CAknFastSwapWindowControl::NumberOfVisibleRows()
{
_AKNTRACE_FUNC_ENTER;
TAknLayoutScalableParameterLimits cellLimits = AknLayoutScalable_Avkon::cell_fast2_pane_ParamLimits();
TInt numberOfGridColumns = cellLimits.LastColumn() + 1;
TInt numberOfGridRows = cellLimits.LastRow() + 1;
TInt numberOfRows = ( iNumberOfWGs - 1 ) / numberOfGridColumns + 1;
if ( numberOfRows <= numberOfGridRows )
{
_AKNTRACE_FUNC_EXIT;
return numberOfRows;
}
else
{
_AKNTRACE_FUNC_EXIT;
return numberOfGridRows;
}
}
// ---------------------------------------------------------
// CAknFastSwapWindowControl::CurrentAppName
// Gives the name of the application with current highlight
// ---------------------------------------------------------
//
TPtrC CAknFastSwapWindowControl::CurrentAppName()
{
_AKNTRACE_FUNC_ENTER;
TInt textindex = iGrid->CurrentDataIndex();
TPtrC name;
if ( textindex > 0 )
{
name.Set( iGrid->Model()->ItemText( textindex ) );
name.Set( name.Mid( name.Find(KTab)+1 ) );
}
_AKNTRACE_FUNC_EXIT;
return name;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::CreateStylusPopupMenu
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::CreateStylusPopupMenuL()
{
_AKNTRACE_FUNC_ENTER;
if ( !iPopupMenu )
{
iPopupMenu = CAknStylusPopUpMenu::NewL( this, Rect().iTl );
HBufC* openText = StringLoader::LoadLC( R_QTN_FSW_STYLUSPOPUPMENU_OPEN );
HBufC* exitText = StringLoader::LoadLC( R_QTN_FSW_STYLUSPOPUPMENU_EXIT );
iPopupMenu->AddMenuItemL( *openText, EAknCapServerCmdOpen );
iPopupMenu->AddMenuItemL( *exitText, EAknCapServerCmdClose );
CleanupStack::PopAndDestroy( exitText );
CleanupStack::PopAndDestroy( openText );
}
_AKNTRACE_FUNC_EXIT;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::ShowPopupMenuL
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::ShowPopupMenuL()
{
_AKNTRACE_FUNC_ENTER;
if ( !iPopupMenu )
{
CreateStylusPopupMenuL();
}
if( iIsStylusPopupShow )
{
_AKNTRACE_FUNC_EXIT;
return;
}
iIsStylusPopupShow = ETrue;
iTooltipModeTouch = EFalse;
SetPointerCapture( EFalse );
RWindowGroup& rootWin = iCoeEnv->RootWin();
TInt index = iGrid->CurrentDataIndex();
index = index < 0 ? 0 : index;
if ((*iShownWgIds)[index].iIsSystemApp)
{
iPopupMenu->SetItemDimmed( EAknCapServerCmdClose, ETrue );
}
else
{
iPopupMenu->SetItemDimmed( EAknCapServerCmdClose, EFalse );
}
iTooltip->HideInfoPopupNote();
TPoint pos = PositionRelativeToScreen();
TInt itemIndex = iGrid->CurrentItemIndex();
itemIndex = itemIndex < 0 ? 0 : itemIndex;
TPoint posItem = iGrid->View()->ItemPos( itemIndex );
if( posItem.iY < iGrid->View()->ViewRect().iTl.iY )
{
posItem.iY = iGrid->View()->ViewRect().iTl.iY;
}
pos.iY += posItem.iY;
pos.iX += posItem.iX;
if ( AknLayoutUtils::LayoutMirrored() )
{
TInt itemWidth = iGrid->View()->ItemSize( itemIndex ).iWidth;
pos.iX += itemWidth;
}
iPopupMenu->SetPosition( pos, CAknStylusPopUpMenu::EPositionTypeLeftBottom );
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
// feedback on menu opening
feedback->InstantFeedback( ETouchFeedbackPopUp );
}
iPopupMenu->ShowMenu();
_AKNTRACE_FUNC_EXIT;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::TryCloseApplicationL
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::TryCloseApplicationL( TInt aIndex, TBool aIsShift )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] aIndex = %d aIsShift = %d", __FUNCTION__, aIndex, aIsShift );
if ( aIndex == KErrNotFound || (*iShownWgIds)[aIndex].iIsSystemApp)
{
_AKNTRACE_FUNC_EXIT;
return;
}
iConfirmCloseWgId = (*iShownWgIds)[aIndex].iWgId;
// if this leaves, okToClose will be left as ETrue
iTooltip->HideInfoPopupNote();
iIsClosing = ETrue;
if (iWidgetsSupported && iWidgetList->IsWidget( iConfirmCloseWgId ))
{
TWsEvent event;
event.SetType(EEventUser);
TUid widgetUid = iWidgetList->IndexToAppUid(aIndex, iAlwaysShownList->iAppList->Count());
TInt32 widgetAppUiUidInt = KWidgetAppUid.iUid;
TInt32 widgetUidInt = widgetUid.iUid;
TUint8* eventData = event.EventData();
// Fill bits 0-31 with widget application Uid.
(TUint32&)*eventData = widgetAppUiUidInt;
eventData+=sizeof(TUint32);
// Fill bits 32-63 with uid of the widget that should be closed.
(TUint32&)*eventData = widgetUidInt;
// Send the event to Widget AppUi.
iEikonEnv->WsSession().SendEventToWindowGroup(iWidgetAppUiWgId, event);
}
else if ( aIsShift )
{
TApaTask task( iEikonEnv->WsSession() );
task.SetWgId( iConfirmCloseWgId );
task.SendSystemEvent( EApaSystemEventShutdown);
}
else
{
TWsEvent event;
event.SetTimeNow();
event.SetType(KAknShutOrHideApp);
iEikonEnv->WsSession().SendEventToWindowGroup(iConfirmCloseWgId, event);
}
_AKNTRACE_FUNC_EXIT;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::SetEmphasis
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::SetEmphasis(CCoeControl* /* aMenuControl */,TBool /* aEmphasis */)
{
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::SetHiddenFlag
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::SetHiddenFlag()
{
_AKNTRACE_FUNC_ENTER;
if ( iIsStylusPopupShow )
{
SetPointerCapture( ETrue );
iIsStylusPopupShow = EFalse;
}
_AKNTRACE_FUNC_EXIT;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::PointerEventL
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::PointerEventL( const TPointerEvent& aEvent )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE( "[%s] event type = %d", __FUNCTION__, aEvent.iType );
if ( ( iState == EShowingAnimation || iState == EWaitingForAnimation ) &&
aEvent.iType == TPointerEvent::EDrag )
{
// Test whether the pointer event is filtered.
TInt offset = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW * 2 / 5;
TRect dragMaxRect( iAnimationPosition.iX - offset, iAnimationPosition.iY - offset,
iAnimationPosition.iX + offset, iAnimationPosition.iY + offset );
if ( dragMaxRect.Contains( aEvent.iParentPosition ) )
{
_AKNTRACE_FUNC_EXIT;
return;
}
}
// Whatever happens, cancel the timer and stop animation.
iTimeOut->Cancel();
StopAnimation();
iState = EWaiting;
iAnimationPosition = aEvent.iParentPosition;
if ( iIsStylusPopupShow )
{
_AKNTRACE_FUNC_EXIT;
// Do not start animation when the stylus popup menu is displayed.
return;
}
if ( aEvent.iType == TPointerEvent::EButton1Down )
{
TInt touchedIndex = KErrNotFound;
TBool isOverItem =
iGrid->GridView()->XYPosToItemIndex( aEvent.iPosition,
touchedIndex);
if( isOverItem && touchedIndex != iGrid->CurrentItemIndex())
{
iGrid->View()->ItemDrawer()->SetFlags( CListItemDrawer::EPressedDownState );
touchedIndex = iGrid->GridView()->ActualDataIndex( touchedIndex );
iGrid->SetCurrentDataIndex(touchedIndex);
iGrid->DrawDeferred();
}
ShowTooltipTouchL( ETrue );
iState = EWaitingForAnimation;
iTimeOut->Start(
KTimeDelayBeforeAnimation,
KTimeNeverHappenEvent,
TCallBack( TimeOutCallBackL, this ) );
}
_AKNTRACE_FUNC_EXIT;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::ToolTipTimeOutCallBackL
// ----------------------------------------------------------------------------
//
TInt CAknFastSwapWindowControl::ToolTipTimeOutCallBackL( TAny* aPtr )
{
(STATIC_CAST(CAknFastSwapWindowControl*,aPtr))->HideTooltip();
return KErrNone ;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::HideTooltip
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::HideTooltip()
{
iToolTipTimer->Cancel();
iTooltip->HideInfoPopupNote();
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::TimeOutCallBackL
// ----------------------------------------------------------------------------
//
TInt CAknFastSwapWindowControl::TimeOutCallBackL( TAny* aPtr )
{
(STATIC_CAST(CAknFastSwapWindowControl*,aPtr))->ShowAnimationL();
return KErrNone ;
}
// ---------------------------------------------------------------------------
// Handles the state changes in the long tap animation.
// ---------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::ShowAnimationL()
{
_AKNTRACE_FUNC_ENTER;
if ( AknLayoutUtils::PenEnabled() )
{
switch ( iState )
{
case EWaitingForAnimation:
{
iState = EShowingAnimation;
iTimeOut->Cancel();
StartAnimationL();
iTimeOut->Start( KLongTapDelay - KTimeDelayBeforeAnimation,
KTimeNeverHappenEvent,
TCallBack( TimeOutCallBackL, this ) );
break;
}
case EShowingAnimation:
case EShowingPressedDownEffect:
{
iState = EShowingPressedDownEffect;
iTimeOut->Cancel();
StopAnimation();
ShowPopupMenuL();
iGrid->View()->ItemDrawer()->ClearFlags( CListItemDrawer::EPressedDownState );
iState = EWaiting;
break;
}
default:
{
break;
}
}
}
_AKNTRACE_FUNC_EXIT;
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::StartAnimationL
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::StartAnimationL()
{
iIsAnimationShowing = ETrue;
iLongTapAnimation->ShowAnimationL( iAnimationPosition.iX,
iAnimationPosition.iY );
}
// ----------------------------------------------------------------------------
// CAknFastSwapperWindowControl::StopAnimationL
// ----------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::StopAnimation()
{
if ( iLongTapAnimation )
{
if ( iIsAnimationShowing )
{
iIsAnimationShowing = EFalse;
iLongTapAnimation->HideAnimation();
}
}
}
// ---------------------------------------------------------------------------
// CAknFastSwapperWindowControl::CancelAnimationAndPressDownEffect
// ---------------------------------------------------------------------------
//
void CAknFastSwapWindowControl::CancelAnimationAndPressDownEffect()
{
_AKNTRACE_FUNC_ENTER;
iTimeOut->Cancel();
StopAnimation();
iState = EWaiting;
iItemDraggingActioned = ETrue;
CListItemDrawer* itemDrawer = iGrid->View()->ItemDrawer();
if ( itemDrawer->Flags() & CListItemDrawer::EPressedDownState )
{
// Clear the pressed down state from the drawer and draw the
// the normal highlight on the highlighter item.
iGrid->View()->ItemDrawer()->ClearFlags( CListItemDrawer::EPressedDownState );
iGrid->DrawItem( iGrid->CurrentItemIndex() );
}
_AKNTRACE_FUNC_EXIT;
}
// End of File