diff -r 000000000000 -r 2f259fa3e83a uifw/EikStd/coctlsrc/EIKMENUB.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/EikStd/coctlsrc/EIKMENUB.CPP Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,1466 @@ +/* +* Copyright (c) 1997-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: +* +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // AKNLAF +#include +#include + +#include +#include +#include "LAFMENUB.H" +#include "LAFMENUP.H" +#include "eikmop.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "avkoninternalpskeys.h" //KAknMenuOptionNoTaskSwapper +#include +#include + +#include + +#include +#include +#include "aknitemactionmenuregister.h" +#include +#include "akntrace.h" + +enum { EEikMenuBarTitleArrayGranularity=10 }; +enum { EEikMenuBarPosArrayGranularity=2 }; +const TInt KExtraBaselineOffsetForFirstPaneItem=4; + +NONSHARABLE_CLASS(CEikMenuBarExtension) : public CBase, public MAknFadedComponent + { +public: + static CEikMenuBarExtension* NewL(CEikMenuBar* aBar); + ~CEikMenuBarExtension(); + + void FadeBehindPopup(TBool aFade); + + /** + * Sets item specific commands dimmed if highlight is not visible. + */ + void SetItemCommandsDimmedL(); + + /** + * Saves current value of iItemActionMenu->CollectionHighlightVisible() to + * a member variable iCollectionHighlightVisible + */ + void StoreCollectionHighlightValue(); +public: // from MAknFadedComponent + TInt CountFadedComponents(); + CCoeControl* FadedComponent(TInt aIndex); + +private: + CEikMenuBarExtension(CEikMenuBar* aBar); + void ConstructL(); + +private: + CEikMenuBar* iBar; + TAknPopupFader iFader; +public: + TInt iContextMenuTitleResourceId; + TInt iOriginalMenuTitleResourceId; + + CEikMenuBar::TMenuType iMenuType; + + + // controls fader and transition aborting behaviour + // with transition effects + TBool iDoingMenuCloseTransition; + + /** + * Item action menu. + * Not own. + */ + CAknItemActionMenu* iItemActionMenu; + + /** + * When menu pane is opened this value is updated to store the value about + * collection highlight visibility + */ + TBool iCollectionHighlightVisible; + }; + + +CEikMenuBarExtension* CEikMenuBarExtension::NewL(CEikMenuBar* aBar) + { + CEikMenuBarExtension* self = new(ELeave) CEikMenuBarExtension(aBar); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CEikMenuBarExtension::~CEikMenuBarExtension() + { + AknItemActionMenuRegister::UnregisterMenuBar( *iBar ); + iBar = NULL; + } + +void CEikMenuBarExtension::FadeBehindPopup(TBool aFade) + { + _AKNTRACE_FUNC_ENTER; + _AKNTRACE( "iDoingMenuCloseTransition: %d", iDoingMenuCloseTransition ); + if( iDoingMenuCloseTransition == EFalse ) + { + iFader.FadeBehindPopup(this, iBar, aFade); + } + _AKNTRACE_FUNC_EXIT; + } + + +void CEikMenuBarExtension::SetItemCommandsDimmedL() + { + if ( !iItemActionMenu ) + { + AknItemActionMenuRegister::RegisterMenuBarL( *iBar ); + } + // hide item-specific commands if highlight not visible + if ( iBar->GetMenuType() != CEikMenuBar::EMenuContext + && iItemActionMenu + && !iItemActionMenu->CollectionHighlightVisible() ) + { + iBar->iMenuPane->SetItemCommandsDimmed(); + } + } + + +void CEikMenuBarExtension::StoreCollectionHighlightValue() + { + if ( iItemActionMenu ) + { + iCollectionHighlightVisible + = iItemActionMenu->CollectionHighlightVisible(); + } + } +CEikMenuBarExtension::CEikMenuBarExtension(CEikMenuBar* aBar) + :iBar(aBar), + iDoingMenuCloseTransition(EFalse), + iItemActionMenu( NULL ) + { + } + +void CEikMenuBarExtension::ConstructL() + { + } + +TInt CEikMenuBarExtension::CountFadedComponents() + { + TInt count = 1; // the cba + + // count the menu pane and it's cascade panes + CEikMenuPane* pane = iBar->iMenuPane; + while (pane) + { + count++; + pane = pane->CascadeMenuPane(); + } + + return count; + } + +CCoeControl* CEikMenuBarExtension::FadedComponent(TInt aIndex) + { + if (aIndex == 0) + return iBar->iMenuCba; + + // count down the list of cascade menus to find the one in question + aIndex--; + CEikMenuPane* pane = iBar->iMenuPane; + while (aIndex > 0 && pane != NULL) + { + aIndex--; + pane = pane->CascadeMenuPane(); + } + + return pane; + } + + +// +// class CTitleArray +// + +EXPORT_C CEikMenuBar::CTitleArray::~CTitleArray() + { + ResetAndDestroy(); + } + +EXPORT_C CEikMenuBar::CTitleArray::CTitleArray() + : CArrayPtrFlat(EEikMenuBarTitleArrayGranularity) + { + __DECLARE_NAME(_S("CEikMenuBar::CTitleArray")); + } + +/** + * Adds the menu bar title aMenuTitle to the end of the array owned by the menu bar + * and transfers ownership. + */ +EXPORT_C void CEikMenuBar::CTitleArray::AddTitleL(CEikMenuBarTitle* aMenuTitle) + { + AppendL(aMenuTitle); + } + + +void CEikMenuBar::CTitleArray::DeleteResource(TInt aResource) + { + TInt count = Count(); + for (TInt ii=0; iiiData.iMenuPaneResourceId == aResource) + { + delete title; + Delete(ii); + return; + } + } + } + + + +// +// class CEikMenuBarTitle +// + +//const TInt KTitleGranularity=1; +//const TInt KIconOwnedExternally = 0x01; +//const TInt KSameBitmapAndMask = 0x10; +//const TInt KTitleWithImageMask = 0xf000; + + +EXPORT_C CEikMenuBarTitle::CEikMenuBarTitle() + {} + +EXPORT_C CEikMenuBarTitle::~CEikMenuBarTitle() + { + delete iIcon; + } + +EXPORT_C void CEikMenuBarTitle::SetIcon(CGulIcon* aIcon) + { + if (iIcon) + delete iIcon; + iIcon = aIcon; + } + +/** + * Returns the value of the extra left margin for the title text which will take into account the + * width of the title icon. + */ +TInt CEikMenuBarTitle::ExtraLeftMargin() const + { + CFbsBitmap* bitmap = IconBitmap(); + TInt extraMargin = 0; + if (bitmap != NULL) + extraMargin = bitmap->SizeInPixels().iWidth; + return extraMargin; + } + +/** + * Adjusts the value of the title text baseline offset aBaseLine to take into account the any + * size of any title icon. + */ +void CEikMenuBarTitle::CalculateBaseLine(TInt& aBaseLine, TInt& aTitleHeight) + { + CFbsBitmap* bitmap = IconBitmap(); + if (bitmap != NULL) + { + TInt tempBaseline = aBaseLine; + const TSize bitmapSize(bitmap->SizeInPixels()); + if (bitmapSize.iHeight > aTitleHeight) + { + tempBaseline += ((bitmapSize.iHeight - aTitleHeight) >> 1); + aTitleHeight = bitmapSize.iHeight; + } + if (tempBaseline > aBaseLine) + aBaseLine = tempBaseline; + } + } + +/** + * Draws the title icon to the graphics context aGc, inside the rect aRect with an offset from the left side of + * the rectangle of size aLeftMargin + */ +EXPORT_C void CEikMenuBarTitle::DrawIcon(CWindowGc& aGc, TRect aRect, TInt aLeftMargin) const + { + CFbsBitmap* bitmap = IconBitmap(); + if (bitmap != NULL) + { + TSize imageSize = bitmap->SizeInPixels(); + aRect.iTl.iX += aLeftMargin; + TInt height = aRect.iBr.iY - aRect.iTl.iY; + if (height > imageSize.iHeight) + aRect.iTl.iY += (TInt) ((height - imageSize.iHeight) / 2 ); + aGc.BitBltMasked(aRect.iTl, bitmap, imageSize, IconMask(), ETrue); + } + } + +/** + * Sets the title icon to be ownded externally if aOwnedExternally is ETrue. + */ +EXPORT_C void CEikMenuBarTitle::SetBitmapsOwnedExternally(TBool aOwnedExternally) + { + iIcon->SetBitmapsOwnedExternally(aOwnedExternally); + } + +/** + * Returns a pointer to the picture bitmap of the title icon. + * Does not normally imply transfer of ownership. + */ +EXPORT_C CFbsBitmap* CEikMenuBarTitle::IconBitmap() const + { + if (iIcon) + return iIcon->Bitmap(); + return NULL; + } + +/** + * Returns a pointer to the mask bitmap of the title icon. + * Does not normally imply transfer of ownership. + */ +EXPORT_C CFbsBitmap* CEikMenuBarTitle::IconMask() const + { + if (iIcon) + return iIcon->Mask(); + return NULL; + } + +/** + * Sets the picture bitmap for the title icon to aBitmap. + * Transfers ownership unless the bitmaps are owned externally. + */ +EXPORT_C void CEikMenuBarTitle::SetIconBitmapL(CFbsBitmap* aBitmap) + { + if (!iIcon) + iIcon=CGulIcon::NewL(); + + iIcon->SetBitmap(aBitmap); + } + +/** + * Sets the mask bitmap for the title icon to aMask. + * Transfers ownership unless the bitmaps are owned externally. + */ +EXPORT_C void CEikMenuBarTitle::SetIconMaskL(CFbsBitmap* aMask) + { + if (!iIcon) + iIcon=CGulIcon::NewL(); + + iIcon->SetMask(aMask); + } + +/** + * Constructs an new icon for the title, taking ownership of the picture bitmap + * aBitmap and the mask bitmap aMask unless the icon bitmaps have been set to be + * owned externally. + */ +EXPORT_C void CEikMenuBarTitle::CreateIconL(CFbsBitmap* aBitmap, CFbsBitmap* aMask) + { + if (iIcon) + delete iIcon; + iIcon = CGulIcon::NewL(aBitmap, aMask); + } + + +// +// class CEikMenuBar +// + +//const TInt KEikMenuBarHBorder=8; +//const TInt KEikMenuBarVBorder=2; +//const TInt KEikMenuMnenPad=3; +//const TInt KEikMaxMenuTitlePadding=10; +//const TInt KEikNumOfSideButtons=5; +//const TInt KEikSidebarPopupXPos=5; +//const TInt KMenuPaneOverlap=1; + +//const TInt KMenuTitleLeftSpace = 12; +//const TInt KMenuTitleRightSpace = 12; +//const TInt KMenuTitleLeftSmallSpace = 2; +//const TInt KMenuTitleRightSmallSpace = 2; + +inline TBool CEikMenuBar::MenuHasItems() const + { + return iMenuFlags&EMenuHasItems; + } + +inline void CEikMenuBar::SetMenuHasItems() + { + iMenuFlags|=EMenuHasItems; + iExt->StoreCollectionHighlightValue(); + } + +inline TBool CEikMenuBar::MenuHasPane() const + { + return iMenuFlags&EMenuHasPane; + } + +inline void CEikMenuBar::SetMenuHasPane() + { + iMenuFlags|=EMenuHasPane; + } + +inline TBool CEikMenuBar::TitleArrayOwnedExternally() const + { + return iMenuFlags&ETitleArrayOwnedExternally; + } + +EXPORT_C CEikMenuBar::~CEikMenuBar() + { + AKNTASHOOK_REMOVE(); + // Inform FEP about the destruction. + MEikMenuObserver* fepMenuObserver = CAknEnv::Static()->FepMenuObserver(); + if ( fepMenuObserver ) + { + fepMenuObserver->ProcessCommandL( EAknCmdEditMenuClose ); + } + + delete iPastMenuPosArray; + iPastMenuPosArray = NULL; + + delete iHotKeyTable; + iHotKeyTable = NULL; + + if ( iMenuPane ) + { + // make sure imenupane is not visible + // otherwise Deregister may try to draw + // when closing application + iMenuPane->MakeVisible( EFalse ); + // deregister main options menu component + GfxTransEffect::Abort( iMenuPane ); + GfxTransEffect::Deregister( iMenuPane ); + delete iMenuPane; + iMenuPane = NULL; + } + + if ( !TitleArrayOwnedExternally() && iTitleArray ) + { + ResetTitleArray(); + delete iTitleArray; + iTitleArray = NULL; + } + + delete iExt; + iExt = NULL; + + if ( iMenuCba ) // should have been deleted before, but still... + { + delete iMenuCba; + iMenuCba = NULL; + } + + iMenuObserver = NULL; // not owned + iEditMenuObserver = NULL; + iActiveEditMenuObserver = NULL; + + } + +EXPORT_C CEikMenuBar::CEikMenuBar() + : iSelectedTitle(ENothingSelected) + { + __DECLARE_NAME(_S("CEikMenuBar")); + iBorder=TGulBorder(AknBorderId::EAknBorderMenuPopup); + AKNTASHOOK_ADD( this, "CEikMenuBar" ); + } + +/** + * Resets the menu bar's title array and destroys its elements. + * + * @since ER5U + */ +void CEikMenuBar::ResetTitleArray() + { + if (iTitleArray) + iTitleArray->ResetAndDestroy(); + } + +/** + * Creates a new menu bar title array if one does not already exist. Resets and destroys the elements + * of an existing array.. + * + * @since ER5U + */ +void CEikMenuBar::CreateTitleArrayL() + { + if (iTitleArray) + iTitleArray->ResetAndDestroy(); + else + iTitleArray=new(ELeave) CTitleArray; + } + +/** + * Sets the flags on the menu pane owned by the menu bar to aFlags. + * + * @since ER5U + */ +void CEikMenuBar::SetMenuPaneFlag(TInt aFlag) + { + iMenuPane->SetScrollBarOnLeft(aFlag&EEikMenuItemScrollBarLeft); + iMenuPane->SetArrowHeadScrollBar(aFlag&EEikMenuItemScrollBarArrowHead); + } + + +EXPORT_C void CEikMenuBar::ConstructL(MEikMenuObserver* aMenuObserver,TInt aHotKeyResourceId,TInt aMenuTitleResourceId) + { + iExt = CEikMenuBarExtension::NewL(this); + + iMenuObserver=aMenuObserver; + iMenuHotKeyResourceId=aHotKeyResourceId; + iMenuTitleResourceId=aMenuTitleResourceId; + iBaseLine=iEikonEnv->NormalFont()->AscentInPixels()+KExtraBaselineOffsetForFirstPaneItem; + iPastMenuPosArray=new(ELeave) CArrayFixFlat(EEikMenuBarPosArrayGranularity); + CreateTitleArrayL(); + + iMenuPane=new(ELeave) CEikMenuPane(iMenuObserver); + iMenuPane->SetMopParent(this); + iMenuPane->SetBorder(AknBorderId::EAknBorderMenuPopup); + iMenuPane->SetParent( this ); + MakeVisible(EFalse); + // register main options menu component + GfxTransEffect::Register( iMenuPane, KGfxOptionsMenuControlUid, EFalse ); + GfxTransEffect::Enable(); + } + +/** + * Constructs the menu bar using the resource reader aReader. + */ +EXPORT_C void CEikMenuBar::ConstructFromResourceL(TResourceReader& aReader) + { + TInt count=aReader.ReadInt16(); + while (count--) + { + CEikMenuBarTitle* title = new(ELeave) CEikMenuBarTitle; + CleanupStack::PushL(title); + title->iData.iMenuPaneResourceId=aReader.ReadInt32(); + title->iTitleFlags=0; + const TPtrC ptr=aReader.ReadTPtrC(); + title->iData.iText=ptr; + title->iTitleFlags=aReader.ReadInt32(); + // Skip over icon info + aReader.ReadTPtrC(); + aReader.ReadInt16(); + aReader.ReadInt16(); + iTitleArray->AddTitleL(title); + aReader.ReadInt32(); // extension link + CleanupStack::Pop(); + } + aReader.ReadInt32(); // extension link + } + +EXPORT_C void CEikMenuBar::FindCommandIdInResourceL(TInt aCommandId,TInt& aPaneindex,TInt& aItemindex) + { + aPaneindex=-1; + aItemindex=-1; + TResourceReader reader; + + TInt panes=iTitleArray->Count(); + for (TInt pindex=0;pindexCreateResourceReaderLC(reader,title->iData.iMenuPaneResourceId); + const TInt count=reader.ReadInt16(); + for (TInt iindex=0;iindex=0) + { + aPaneindex=pindex; + CleanupStack::PopAndDestroy(); // buffer(reader) + return; + } + CleanupStack::PopAndDestroy(); // buffer(reader) + } + } + + +EXPORT_C void CEikMenuBar::ChangeMenuBarL(TInt /*aHotKeyResourceId*/,TInt /*aMenuTitleResourceId*/,TBool /*aDisplayNow*/) + { + } + +void CEikMenuBar::SaveCurrentMenuPositionL() +//Save position on current menu +//See if current menu is already on past menu array. +//If it is, just change the cursor value, if it is not +//add a new element to the array. + { + const TInt count = iPastMenuPosArray->Count(); + for (TInt ii = 0; ii < count; ++ii) + { + if ((*iPastMenuPosArray)[ii].iMenuId == iMenuTitleResourceId) + { + (*iPastMenuPosArray)[ii].iMenuCursorPos = iCursor; + return; + } + } + SPosition menuPos; + menuPos.iMenuId = iMenuTitleResourceId; + menuPos.iMenuCursorPos = iCursor; + iPastMenuPosArray->AppendL(&menuPos, sizeof(menuPos)); + } + +void CEikMenuBar::SetCursorPositionFromArray() +//Set cursor position +//Check position array to see if menu previously displayed and use that last position. + { + const TInt count=iPastMenuPosArray?iPastMenuPosArray->Count():0; + for (TInt ii=0;iiSetSelectedItem(0); + } + iSelectedTitle=ENothingSelected; + iMenuTitleResourceId=aMenuTitleResourceId; + } + +EXPORT_C void CEikMenuBar::SetContextMenuTitleResourceId(TInt aMenuTitleResourceId) + { + SetCursorPositionFromArray(); // defaults set here if this menu not previously displayed + if (iMenuPane && !MenuHasPane()) + { + iMenuPane->SetSelectedItem(0); + } + iSelectedTitle=ENothingSelected; + iExt->iContextMenuTitleResourceId=aMenuTitleResourceId; + } + +EXPORT_C void CEikMenuBar::SetMenuTitleArray(CTitleArray* /*aTitleArray*/) + { + } + +/** + * Sets the menu bar title array to be owned externally if aOwnedExternally is ETrue. + * + * since ER5U + */ +EXPORT_C void CEikMenuBar::SetTitleArrayOwnedExternally(TBool /*aOwnedExternally*/) + { + } + +EXPORT_C TKeyResponse CEikMenuBar::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + const TInt code=aKeyEvent.iCode; + + if (MenuHasPane()) + { + iMenuPane->OfferKeyEventL(aKeyEvent, aType); + return (aKeyEvent.iScanCode == EStdKeyYes ? EKeyWasNotConsumed : EKeyWasConsumed); + } + else + { + switch (code) + { + case EEikSidebarMenuKey: + case EKeyMenu: + TryDisplayMenuBarL(); + return EKeyWasConsumed; + default: + break; + } + } + + if (!MenuHasItems()) // menu bar not currently displayed + return EKeyWasNotConsumed; + + // When displaying, the menu bar must comsume all keys, even those it doesn't use. + // So use callback here to see if app wants key. + iMenuObserver->OfferKeyToAppL(aKeyEvent, aType); + return EKeyWasConsumed; + + } + + + +LOCAL_C void CleanupMenu(TAny* aPtr) + { + ((CEikMenuBar*)aPtr)->StopDisplayingMenuBar(); + } + +EXPORT_C TInt CEikMenuBar::SelectedTitle() + { + return iCursor.iMenuPaneIndex; + } + +EXPORT_C TInt CEikMenuBar::SelectedItem() + { + return iCursor.iMenuItemIndex; + } + +EXPORT_C void CEikMenuBar::TryDisplayMenuBarL() + { + if (MenuHasItems()) + return; // menu already being displayed + iActiveEditMenuObserver = iEditMenuObserver; + CleanupStack::PushL(TCleanupItem(CleanupMenu,this)); + StartDisplayingMenuBarL(); + CleanupStack::Pop(); + } + +EXPORT_C void CEikMenuBar::TryDisplayContextMenuBarL() + { + if (MenuHasItems() || !iExt || !iExt->iContextMenuTitleResourceId) + return; // menu already being displayed or no extension or no context resource id + iActiveEditMenuObserver = iEditMenuObserver; + CleanupStack::PushL(TCleanupItem(CleanupMenu,this)); + // use context specific menu resource for this menu + iExt->iOriginalMenuTitleResourceId = iMenuTitleResourceId; + iMenuTitleResourceId = iExt->iContextMenuTitleResourceId; + SetMenuType(EMenuContext); + StartDisplayingMenuBarL(); + CleanupStack::Pop(); + } + + +void CEikMenuBar::HideMenuPane() + { + if (MenuHasPane()) + { + iCursor.iMenuPaneIndex=iSelectedTitle; // !! check this can never be -1 + iCursor.iMenuItemIndex=iMenuPane->SelectedItem(); + iMenuPane->CancelActiveMenuPane(); + iMenuFlags&=~EMenuHasPane; + iMenuPane->Reset(); + iMenuPane->MakeVisible(EFalse); + } + iSelectedTitle=ENothingSelected; + } + + +EXPORT_C void CEikMenuBar::MoveHighlightToL(TInt /*aNewSelectedTitle*/,TInt /*aNewSelectedItem*/) + { + } + +EXPORT_C void CEikMenuBar::StopDisplayingMenuBar() + { + _AKNTRACE_FUNC_ENTER; + if (iMenuFlags&ESoundsInstalled) + { + iAvkonAppUi->KeySounds()->PopContext(); + iMenuFlags &= ~ESoundsInstalled; + } + if( !iExt->iDoingMenuCloseTransition && IsDisplayed() ) + { + // abort component effects + GfxTransEffect::Abort(); + } + + iAvkonEnv->UnRegisterIntermediateState(this); + + delete iMenuCba; + iMenuCba = NULL; + + iMenuObserver->SetEmphasis(this,EFalse); + iMenuFlags&=~EMenuHasItems; + HideMenuPane(); + MEikMenuObserver* fepMenuObserver = CAknEnv::Static()->FepMenuObserver(); + if (fepMenuObserver) + fepMenuObserver->SetEmphasis(this, EFalse); + if (iActiveEditMenuObserver) + iActiveEditMenuObserver->SetEmphasis(this, EFalse); + iActiveEditMenuObserver=NULL; // forget active observer till menu next added + iMenuPane->SetFocus(EFalse); + iMenuPane->Close(); + iTitleArray->ResetAndDestroy(); + if (OwnsWindow()) + CloseWindow(); + + // normal options menu must be restored if context specific menu was displayed + if (iExt && iMenuTitleResourceId == iExt->iContextMenuTitleResourceId && + iExt->iOriginalMenuTitleResourceId) + { + iMenuTitleResourceId = iExt->iOriginalMenuTitleResourceId; + SetMenuType(EMenuOptions); + } + + if (iMenuFlags&EBackgroundFaded) + { + if (iExt) + iExt->FadeBehindPopup(EFalse); + iMenuFlags &= ~EBackgroundFaded; + } + _AKNTRACE_FUNC_EXIT; + } + +void CEikMenuBar::StartDisplayingMenuBarL() + { + _AKNTRACE_FUNC_ENTER; + // Inform AIW framework that a menu bar is being launched. + CAiwServiceHandler::ReportMenuLaunch(); + + CreateWindowL(iCoeEnv->RootWin()); + const TSize screenSize = iAvkonAppUi->ApplicationRect().Size(); + + __ASSERT_DEBUG(iMenuCba == NULL, User::Panic(_L("CEikMenuBar"), KErrAlreadyExists)); + TInt softkeyResourceId = R_AVKON_SOFTKEYS_SELECT_CANCEL__SELECT; + if ((User::Language() & KAknLanguageMask) == ELangJapanese) + { + // In Japanese UI language Select-Back softkey combination is used. + // Command Id for Back is same as for Cancel. + softkeyResourceId = R_AVKON_SOFTKEYS_SELECT_BACK__SELECT; + } + + iMenuPane->ConstructL(NULL, iActiveEditMenuObserver); + + MEikMenuObserver* fepMenuObserver = CAknEnv::Static()->FepMenuObserver(); + + iMenuObserver->RestoreMenuL(this,iMenuTitleResourceId,MEikMenuObserver::EMenuBar); + + if (fepMenuObserver) + { + AddFEPMenuL(); + fepMenuObserver->DynInitMenuBarL(iMenuTitleResourceId, this); + } + + TInt titles = iTitleArray->Count() - 1; + + if ( titles < 0 ) + { + delete iMenuCba; + iMenuCba = NULL; + iTitleArray->ResetAndDestroy(); + iMenuPane->Close(); + return; + } + + // Create the menu pane using the last pane in the menu bar + iMenuObserver->RestoreMenuL(iMenuPane,(*iTitleArray)[titles]->iData.iMenuPaneResourceId,MEikMenuObserver::EMenuPane); + if (fepMenuObserver) + fepMenuObserver->DynInitMenuPaneL((*iTitleArray)[titles]->iData.iMenuPaneResourceId,iMenuPane); + if (iActiveEditMenuObserver) + iActiveEditMenuObserver->DynInitMenuPaneL((*iTitleArray)[titles]->iData.iMenuPaneResourceId,iMenuPane); + + titles = iTitleArray->Count() - 2; + iMenuPane->FilterDimmedItems(); + + // Add the remaining menu panes from right to left at the end of the current pane + while (titles >= 0) + { + TInt resource = (*iTitleArray)[titles]->iData.iMenuPaneResourceId; + iMenuPane->AddMenuItemsL(resource, 0, ETrue); + iMenuObserver->DynInitMenuPaneL(resource,iMenuPane); + if (fepMenuObserver) + fepMenuObserver->DynInitMenuPaneL(resource,iMenuPane); + if (iActiveEditMenuObserver) + iActiveEditMenuObserver->DynInitMenuPaneL(resource,iMenuPane); + iExt->SetItemCommandsDimmedL(); + iMenuPane->FilterDimmedItems(); + titles--; + } + iMenuObserver->SetEmphasis(this,ETrue); + iMenuCba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba, + CEikButtonGroupContainer::EHorizontal, + this, softkeyResourceId, *iMenuPane, + CEikButtonGroupContainer::EIsEmbedded | + CEikButtonGroupContainer::EDelayActivation ); + + CEikCba* cba = static_cast( iMenuCba->ButtonGroup() ); + if ( cba ) + { + iMenuPane->SetEmbeddedCba( cba ); + } + + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->FlushRegistryUpdates(); + } + + TInt taskSwapper ( ETaskSwapper ); + RProperty::Get( + KPSUidAvkonInternal, + KAknMenuOptionNoTaskSwapper, + taskSwapper); + if ( iMenuPane->NumberOfItemsInPane() != 0 && iExt->iMenuType == EMenuOptions && taskSwapper == ETaskSwapper ) + { + // 'Active Applications' menu item is added at the first item of the + // options menu after other menu items are added. + iMenuPane->AddMenuItemsL(R_AVKON_MENUPANE_TASK_SWAPPER); + } + + if (iMenuPane->NumberOfItemsInPane() == 0) + { + delete iMenuCba; + iMenuCba = NULL; + iMenuObserver->SetEmphasis(this,EFalse); + iTitleArray->ResetAndDestroy(); + iMenuPane->Close(); + return; + } + + if (!(iMenuFlags&EBackgroundFaded)) + { + iExt->FadeBehindPopup(ETrue); + iMenuFlags |= EBackgroundFaded; + } + + iMenuCba->SetBoundingRect(TRect(TPoint(0,0), screenSize)); + + SetMenuHasPane(); + SetMenuHasItems(); + + TInt positionOffTaskSwapper; + if (iMenuPane->MenuItemExists(EAknCmdTaskSwapper, positionOffTaskSwapper)) + { + // Default selected item is just after 'Active Applications' menu + // item if it exists. + iMenuPane->SetSelectedItem(positionOffTaskSwapper + 1); + } + else + { + iMenuPane->SetSelectedItem( 0 ); + } + + iMenuPane->SetFocus(ETrue); + if (fepMenuObserver) + fepMenuObserver->SetEmphasis(this, ETrue); + if (iActiveEditMenuObserver) + iActiveEditMenuObserver->SetEmphasis(this, ETrue); + + // Set the position of the menu pane to the top of the CBA area, + // and set the width to the width of the screen + TPoint menuPosition = TPoint(0, screenSize.iHeight - iMenuCba->Size().iHeight); + + if(AknLayoutUtils::PenEnabled()) + { + // menu pane captures all pointer events, and forwards them to CBA if neccessary + iMenuPane->SetGloballyCapturing(ETrue); + iMenuPane->SetPointerCapture(ETrue); + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp; + if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + { + fbLogicalType = ETouchFeedbackIncreasingPopUp; + } + feedback->InstantFeedback( + this, + fbLogicalType, + ETouchFeedbackVibra, + TPointerEvent() ); + } + } + + iMenuPane->MakeVisible( EFalse ); + + // options menu launch animation + TBool optMenuFg = iAvkonAppUi->IsForeground(); + + if( optMenuFg ) + { + GfxTransEffect::Begin( iMenuPane, KGfxControlAppearAction ); + } + + iMenuPane->StartDisplayingMenuPane(NULL, menuPosition, NULL, screenSize.iWidth, EPopupTargetBottomLeft); + iMenuCba->ActivateL(); + + iAvkonEnv->RegisterIntermediateStateL(this); + iAvkonAppUi->KeySounds()->PushContextL(R_AVKON_DEFAULT_SKEY_LIST); + iMenuFlags |= ESoundsInstalled; + + if( optMenuFg ) + { + TRect demarcation; + CAknTransitionUtils::GetDemarcation( CAknTransitionUtils::EOptionsMenu, + demarcation ); + GfxTransEffect::SetDemarcation( iMenuPane, demarcation ); + GfxTransEffect::End( iMenuPane ); + } + _AKNTRACE_FUNC_EXIT; + } + + +EXPORT_C void CEikMenuBar::Draw(const TRect& /*aRect*/) const + { + + } + +EXPORT_C void CEikMenuBar::DrawItem(TInt /*aItem*/) const + { + } + +EXPORT_C void* CEikMenuBar::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +EXPORT_C void CEikMenuBar::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + const TRect rect=Rect(); + if (!rect.Contains(aPointerEvent.iPosition)) + { + switch (aPointerEvent.iType) + { + case TPointerEvent::EButton1Down: + case TPointerEvent::EButton1Up: + ProcessCommandL( EAknSoftkeyCancel ); + iMenuObserver->ProcessCommandL(EEikCmdCanceled); // shouldn't Leave in practiceReportCancelled(); + return; + case TPointerEvent::EDrag: + // dragging off a pane sometimes sends the events to the bar; this code redirects the event + // to the pane so that highlighing can be removed. + if (iMenuPane) + { + TPoint panepos= iMenuPane->Position(); + TRect panerect= TRect(panepos, iMenuPane->Size()); + if (!panerect.Contains(aPointerEvent.iPosition)) + { + TPointerEvent aPEvent=aPointerEvent; + aPEvent.iPosition=aPointerEvent.iPosition - panepos; + iMenuPane->HandlePointerEventL(aPEvent); + } + } + return; + default: + return; + } + } + const TInt yPos=aPointerEvent.iPosition.iY; + if (yPos<2 || yPos>iSize.iHeight-2) + return; + const TInt xPos=aPointerEvent.iPosition.iX; + const TInt count=iTitleArray->Count(); + for (TInt ii=0;iiiPos) + return; + if (xPosiPos+title->iWidth) + { + MoveHighlightToL(ii); + return; + } + } + } + +EXPORT_C TCoeInputCapabilities CEikMenuBar::InputCapabilities() const + { + return TCoeInputCapabilities(TCoeInputCapabilities::EAllText); // Max length parameter removed for Release15 + } + +EXPORT_C CEikMenuBar::SCursor CEikMenuBar::SetMenuCursor(const SCursor& aCursor) + { + SCursor ret=iCursor; + iCursor=aCursor; + return ret; + } + +/** + * Gets the list of logical colors employed in the drawing of the control, + * paired with an explanation of how they are used. Appends the list to aColorUseList. + * + * @since ER5U + */ +EXPORT_C void CEikMenuBar::GetColorUseListL(CArrayFix& aColorUseList) const + { + LafMenuBar::GetColorUseListL(aColorUseList); + } + +/** + * Handles a change to the control's resources of type aType + * which are shared across the environment, e.g. colors or fonts. + * + * @since ER5U + */ +EXPORT_C void CEikMenuBar::HandleResourceChange(TInt aType) + { + if ( aType == KEikDynamicLayoutVariantSwitch + || aType == KEikMessageWindowsFadeChange + || aType == KEikMessageUnfadeWindows + || aType == KEikMessageFadeAllWindows + || aType == KAknMessageFocusLost + || ( IsDisplayed() && aType == KAknsMessageSkinChange ) ) + { + if ( iMenuPane ) + { + iMenuPane->HandleResourceChange( aType ); + } + } + } + +EXPORT_C void CEikMenuBar::Reserved_1() + {} + +EXPORT_C void CEikMenuBar::Reserved_2() + {} + +void CEikMenuBar::ProcessCommandL(TInt aCommandId) + { + TRect demarcation; + switch (aCommandId) + { +// AKNLAF start + case EAknSoftkeyOk: + iMenuPane->ActivateCurrentItemL(); + break; + case EAknSoftkeySelect: + iMenuPane->ActivateCurrentItemL(); + break; + case EAknSoftkeyCancel: + // options menu cancel animation, does not apply to the case + // when something is chosen from the menu + GfxTransEffect::Begin( iMenuPane, KGfxControlDisappearAction ); + + iExt->iDoingMenuCloseTransition = ETrue; + StopDisplayingMenuBar(); + iExt->iDoingMenuCloseTransition = EFalse; + + CAknTransitionUtils::GetDemarcation( + CAknTransitionUtils::EOptionsMenu, demarcation ); + GfxTransEffect::SetDemarcation( iMenuPane, demarcation ); + GfxTransEffect::End( iMenuPane ); + + // do the fading a bit later than in StopDisplayingMenuBar + iExt->FadeBehindPopup( EFalse ); + + if ( AknLayoutUtils::PenEnabled() ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp; + if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + { + fbLogicalType = ETouchFeedbackDecreasingPopUp; + } + feedback->InstantFeedback( + this, + fbLogicalType, + ETouchFeedbackVibra, + TPointerEvent() ); + } + } + break; +// AKNLAF end + default: + break; + } + } + + +EXPORT_C void CEikMenuBar::ReduceRect(TRect& aRect) const + { + if (!IsVisible()) + return; + aRect.iTl.iY+=iSize.iHeight; + } + + +void CEikMenuBar::AddFEPMenuL() + { + if (iPreventFepMenu) + { + iPreventFepMenu = EFalse; + iTitleArray->DeleteResource(R_AVKON_MENUPANE_LANGUAGE_DEFAULT); + iTitleArray->DeleteResource(R_AVKON_MENUPANE_EDITTEXT_DEFAULT); + iTitleArray->DeleteResource(R_AVKON_MENUPANE_FEP_DEFAULT); + } + else + { + AddMenuIfNotPresentL(R_AVKON_MENUPANE_LANGUAGE_DEFAULT); + AddMenuIfNotPresentL(R_AVKON_MENUPANE_EDITTEXT_DEFAULT); + AddMenuIfNotPresentL(R_AVKON_MENUPANE_FEP_DEFAULT); + } + } + +void CEikMenuBar::AddMenuIfNotPresentL(TInt aResourceId) + { + TInt titleCount = iTitleArray->Count(); + for (TInt ii=0; iiiData.iMenuPaneResourceId == aResourceId) + return; + } + + // Automatically add the FEP menu to the top of the menu + CEikMenuBarTitle* title = new(ELeave) CEikMenuBarTitle; + CleanupStack::PushL(title); + title->iData.iMenuPaneResourceId = aResourceId; + title->iTitleFlags=0; + iTitleArray->AddTitleL(title); + CleanupStack::Pop(); + } + + +EXPORT_C CEikMenuPane* CEikMenuBar::MenuPane() + { + return iMenuPane; + } + +EXPORT_C CEikMenuBar::CTitleArray* CEikMenuBar::TitleArray() + { + return iTitleArray; + } + +EXPORT_C void CEikMenuBar::SetEditMenuObserver(MEikMenuObserver* aEditMenuObserver) + { + iEditMenuObserver = aEditMenuObserver; + } + +void CEikMenuBar::UpdateTitleTextBaseline() + { + iBaseLine = LafMenuBar::NormalFont(iEikonEnv->LafEnv())->AscentInPixels() + LafMenuBar::ExtraBaselineOffsetForFirstPaneItem(); + if (iTitleArray) + { + const TInt count = iTitleArray->Count(); + TInt maxTitleHeight = LafMenuBar::NormalFont(iEikonEnv->LafEnv())->HeightInPixels(); + TInt baselineOffset = 0; + for (TInt ii = 0; ii < count; ii++) + { + CEikMenuBarTitle* title=(*iTitleArray)[ii]; + title->CalculateBaseLine(iBaseLine, maxTitleHeight); + } + iBaseLine += baselineOffset; + } + } +EXPORT_C void CEikMenuBar::RemoveEditMenuObserver(MEikMenuObserver* aEditMenuObserver) + { + if (iActiveEditMenuObserver == aEditMenuObserver) + iActiveEditMenuObserver = NULL; + if (iEditMenuObserver == aEditMenuObserver) + iEditMenuObserver = NULL; + } + +// +// class CEikMenuPaneTitle +// + +EXPORT_C CEikMenuPaneTitle::CEikMenuPaneTitle(CEikMenuBar* aMenuBar) + : iMenuBar(aMenuBar) + { + AKNTASHOOK_ADD( this, "CEikMenuPaneTitle" ); + } + +EXPORT_C void CEikMenuPaneTitle::ConstructL() + { + } + +EXPORT_C void CEikMenuPaneTitle::SetSelectedTitle(TInt /*aSelectedTitle*/) + { + } + +EXPORT_C void CEikMenuPaneTitle::Draw(const TRect& /*aRect*/) const + { + } + +EXPORT_C void CEikMenuPaneTitle::HandlePointerEventL(const TPointerEvent&) + { + } + +EXPORT_C void* CEikMenuPaneTitle::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +EXPORT_C TMargins CEikMenuPaneTitle::Margins() const + { + return iBorder.Margins(); + } + +EXPORT_C void CEikMenuPaneTitle::Close() + { + } + +/** + * Gets the list of logical colors employed in the drawing of the control, + * paired with an explanation of how they are used. Appends the list to aColorUseList. + * + * @since ER5U + */ +EXPORT_C void CEikMenuPaneTitle::GetColorUseListL(CArrayFix& aColorUseList) const + { + LafMenuPaneTitle::GetColorUseListL(aColorUseList); + } + +/** + * Handles a change to the control's resources of type aType + * which are shared across the environment, e.g. colors or fonts. + * + * @since ER5U + */ +EXPORT_C void CEikMenuPaneTitle::HandleResourceChange(TInt /*aType*/) + { + } +/** + * Allows the client to determine if the menubar instance is displayed ("UP") + * + * @since Avkon + */ +EXPORT_C TBool CEikMenuBar::IsDisplayed() + { + return MenuHasPane(); + } + +EXPORT_C void CEikMenuBar::SetMenuType(TMenuType aMenuType) + { + iExt->iMenuType = aMenuType; + } + +EXPORT_C CEikMenuBar::TMenuType CEikMenuBar::GetMenuType() const + { + return iExt->iMenuType; + } + + +EXPORT_C TBool CEikMenuBar::ItemSpecificCommandsEnabled() const + { + TBool enabled( ETrue ); + if ( MenuHasPane() && iExt->iItemActionMenu ) + { + enabled = iExt->iCollectionHighlightVisible; + } + else if ( iExt->iItemActionMenu && + !iExt->iItemActionMenu->CollectionHighlightVisible() ) + { + enabled = EFalse; + } + return enabled; + } + + +void CEikMenuBar::SetItemActionMenu( CAknItemActionMenu* aItemActionMenu ) + { + if ( aItemActionMenu ) + { + iExt->iItemActionMenu = aItemActionMenu; + iExt->iItemActionMenu->SetMenuBar( iMenuObserver, this ); + } + } + + +CAknItemActionMenu* CEikMenuBar::ItemActionMenu() const + { + return iExt->iItemActionMenu; + } + +CEikMenuPane* CEikMenuBar::PopulateItemActionMenuL( + CAknItemActionMenu& aItemActionMenu ) + { + CEikMenuPane* menuPane( NULL ); + CAiwServiceHandler::ReportMenuLaunch(); + if ( !iExt->iItemActionMenu ) + { + SetItemActionMenu( &aItemActionMenu ); + } + + if ( iMenuTitleResourceId ) + { + menuPane = CEikMenuPane::NewItemCommandMenuL( iMenuObserver ); + CleanupStack::PushL( menuPane ); + iMenuObserver->RestoreMenuL( + this, + iMenuTitleResourceId, + MEikMenuObserver::EMenuBar ); + TInt titles = iTitleArray->Count(); + if ( titles > 0 ) + { + titles--; + while ( titles >= 0 ) + { + TInt resource + = ( *iTitleArray )[ titles ]->iData.iMenuPaneResourceId; + + if ( iCoeEnv->IsResourceAvailableL( resource ) ) + { + menuPane->AddMenuItemsL( resource, 0 ); + iMenuObserver->DynInitMenuPaneL( resource, menuPane ); + } + titles--; + } + menuPane->AddMenuItemsToItemActionMenuL( + iExt->iItemActionMenu->MenuData() ); + } + iTitleArray->ResetAndDestroy(); + CleanupStack::Pop( menuPane ); + } + return menuPane; + } + + +void CEikMenuBar::CloseState() + { + StopDisplayingMenuBar(); + } + +EXPORT_C void CEikMenuBar::TryDisplayMenuBarWithoutFepMenusL() + { + iPreventFepMenu = ETrue; + TryDisplayMenuBarL(); + } + +TTypeUid::Ptr CEikMenuBar::MopSupplyObject(TTypeUid aId) + { + return SupplyMopObject(aId, iMenuCba); + }