diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/CommonUI/src/CPbk2TabGroupContainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/CommonUI/src/CPbk2TabGroupContainer.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,599 @@ +/* +* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Phonebook 2 tab group container. +* +*/ + + +#include "CPbk2TabGroupContainer.h" + +// Phonebook 2 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include +#include +#include +#include +#include + +// Debugging headers +#include + +/// Unnamed namespace for local definitions +namespace { + +/** + * The maximum amount of visible tabs in the tab group. + */ +const TInt KMaxTabsInTabGroup = 4; + +/** + * Returns the topmost tab group. + * + * @return Topmost tab group. + */ +CAknTabGroup* GetTabGroupOnTop() + { + CAknTabGroup* result = NULL; + + CAknNavigationControlContainer* naviPane = + static_cast + ( CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL + ( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + + if ( naviPane ) + { + CAknNavigationDecorator* topDecorator = naviPane->Top(); + if ( topDecorator && topDecorator->ControlType() == + CAknNavigationDecorator::ETabGroup ) + { + result = static_cast( + topDecorator->DecoratedControl() ); + } + } + return result; + } + +} /// namespace + + +/** + * Phonebook 2 tab group entry. + * Responsible for tab groups. Clients may modify the + * tab group through this class. + */ +class CPbk2TabGroupContainer::CPbk2TabGroupEntry : public CBase + { + public: // Construction and destruction + + /** + * Creates a new instance of this class. + * + * @param aTabGroupId Tab group id. + * @param aTabGroup Tab group. + * @return A new instance of this class. + */ + static CPbk2TabGroupEntry* NewL( + TPbk2TabGroupId aTabGroupId, + CAknNavigationDecorator* aTabGroup ); + + /** + * Destructor. + */ + ~CPbk2TabGroupEntry(); + + public: // Interface + + /** + * Returns the tab group id. + * + * @return Tab group id. + */ + inline TPbk2TabGroupId TabGroupId() const; + + /** + * Returns the tab group. + * + * @return Tab group. + */ + inline CAknTabGroup* TabGroup() const; + + /** + * Returns the navigation decorator. + * + * @return Navigation decorator. + */ + inline CAknNavigationDecorator* Decorator() const; + + private: // Implementation + CPbk2TabGroupEntry(TPbk2TabGroupId aTabGroupId, + CAknNavigationDecorator* aTabGroup ); + + private: // Data + /// Own: Phonebook 2 tab group id + TPbk2TabGroupId iTabGroupId; + /// Own: Avkon tab group + CAknNavigationDecorator* iTabGroup; + }; + + +// -------------------------------------------------------------------------- +// CPbk2TabGroupEntry::CPbk2TabGroupEntry +// -------------------------------------------------------------------------- +// +CPbk2TabGroupContainer::CPbk2TabGroupEntry::CPbk2TabGroupEntry + ( TPbk2TabGroupId aTabGroupId, CAknNavigationDecorator* aTabGroup ) : + iTabGroupId( aTabGroupId ), + iTabGroup( aTabGroup ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::CPbk2TabGroupEntry::~CPbk2TabGroupEntry +// -------------------------------------------------------------------------- +// +CPbk2TabGroupContainer::CPbk2TabGroupEntry::~CPbk2TabGroupEntry() + { + delete iTabGroup; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::CPbk2TabGroupEntry::CPbk2TabGroupEntry +// -------------------------------------------------------------------------- +// +CPbk2TabGroupContainer::CPbk2TabGroupEntry* + CPbk2TabGroupContainer::CPbk2TabGroupEntry::NewL + ( TPbk2TabGroupId aTabGroupId, CAknNavigationDecorator* aTabGroup ) + { + CPbk2TabGroupEntry* self = new ( ELeave ) CPbk2TabGroupEntry + ( aTabGroupId, aTabGroup ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroupId +// -------------------------------------------------------------------------- +// +inline TPbk2TabGroupId + CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroupId() const + { + return iTabGroupId; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroup +// -------------------------------------------------------------------------- +// +inline CAknTabGroup* + CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroup() const + { + return static_cast( iTabGroup->DecoratedControl() ); + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupEntry::Decorator +// -------------------------------------------------------------------------- +// +inline CAknNavigationDecorator* + CPbk2TabGroupContainer::CPbk2TabGroupEntry::Decorator() const + { + return iTabGroup; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::CPbk2TabGroupContainer +// -------------------------------------------------------------------------- +// +CPbk2TabGroupContainer::CPbk2TabGroupContainer( + MPbk2ViewExplorer& aViewExplorer, + MPbk2TabGroupContainerCallback& aCallback ) : + iViewExplorer( aViewExplorer ), + iCallback ( aCallback ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::~CPbk2TabGroupContainer +// -------------------------------------------------------------------------- +// +CPbk2TabGroupContainer::~CPbk2TabGroupContainer() + { + delete iTabIcons; + iViewTabGroups.ResetAndDestroy(); + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroup::ConstructL +// -------------------------------------------------------------------------- +// +inline void CPbk2TabGroupContainer::ConstructL() + { + iTabIcons = CPbk2IconInfoContainer::NewL(); + + PBK2_PROFILE_START(Pbk2Profile::ETabGroupCreateTabGroups); + // creates all the tab groups and tabs + CreateTabGroupsL(); + PBK2_PROFILE_END(Pbk2Profile::ETabGroupCreateTabGroups); + + PBK2_PROFILE_START(Pbk2Profile::ETabGroupSkinTabGroups); + // skins the created tabs by looping through all of them + SkinTabGroupsL(); + PBK2_PROFILE_END(Pbk2Profile::ETabGroupSkinTabGroups); + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2TabGroupContainer* CPbk2TabGroupContainer::NewL( + MPbk2ViewExplorer& aViewExplorer, + MPbk2TabGroupContainerCallback& aCallback ) + { + CPbk2TabGroupContainer* self = + new ( ELeave ) CPbk2TabGroupContainer( aViewExplorer, aCallback ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::TabGroupFromViewId +// -------------------------------------------------------------------------- +// +EXPORT_C CAknNavigationDecorator* CPbk2TabGroupContainer::TabGroupFromViewId + ( TInt aId ) const + { + CAknNavigationDecorator* tabGroupDecorator = NULL; + + // Loop through the view tab groups array + const TInt tabGroupCount = iViewTabGroups.Count(); + for (TInt i = 0; i < tabGroupCount; ++i) + { + CAknTabGroup* tabGroup = iViewTabGroups[i]->TabGroup(); + if (tabGroup->TabIndexFromId(aId) >= 0) + { + CAknNavigationDecorator* decorator = + iViewTabGroups[i]->Decorator(); + tabGroupDecorator = decorator; + break; + } + } + + return tabGroupDecorator; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::HandleNavigationKeyEventL +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CPbk2TabGroupContainer::HandleNavigationKeyEventL + ( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TBool result = EFalse; + CAknTabGroup* topTabGroup = GetTabGroupOnTop(); + + if ( topTabGroup ) + { + // Offer key event to be handled to top most tab + result = ( topTabGroup->OfferKeyEventL + ( aKeyEvent, aType ) == EKeyWasConsumed ); + } + + return result; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::TabIcons +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2IconInfoContainer& CPbk2TabGroupContainer::TabIcons() const + { + return *iTabIcons; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::TabChangedL +// -------------------------------------------------------------------------- +// +void CPbk2TabGroupContainer::TabChangedL( TInt aIndex ) + { + CAknTabGroup* topTabGroup = GetTabGroupOnTop(); + if ( topTabGroup ) + { + // View id is stored in the tab + const TInt viewId = topTabGroup->TabIdFromIndex( aIndex ); + + MPbk2AppUi* appUi = Phonebook2::Pbk2AppUi(); + + CPbk2ViewState* activeViewState = + appUi->ActiveView()->ViewStateLC(); + iViewExplorer.ActivatePhonebook2ViewL( TUid::Uid( viewId ), + activeViewState ); + CleanupStack::PopAndDestroy( activeViewState ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::HandleNaviDecoratorEventL +// -------------------------------------------------------------------------- +// +void CPbk2TabGroupContainer::HandleNaviDecoratorEventL( TInt aEventID ) + { + if ( AknLayoutUtils::PenEnabled() ) + { + CAknTabGroup* topTabGroup = GetTabGroupOnTop(); + if ( topTabGroup ) + { + topTabGroup->HandleNaviDecoratorEventL( aEventID ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::DoCalculateTabGroupWidth +// -------------------------------------------------------------------------- +// +TInt CPbk2TabGroupContainer::DoCalculateTabGroupWidth + ( TInt aViewCount ) const + { + TInt width = EAknTabWidthWithOneTab; + switch ( aViewCount ) + { + case 1: + width = EAknTabWidthWithOneTab; + break; + case 2: + width = EAknTabWidthWithTwoTabs; + break; + case 3: + width = EAknTabWidthWithThreeTabs; + break; + case 4: + width = EAknTabWidthWithFourTabs; + break; + } + if (aViewCount > KMaxTabsInTabGroup) + { + // n tabs is the maximum amount visible + width = EAknTabWidthWithFourTabs; + } + + return width; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::DoReadViewNodeTabResourcesL +// Reads a PBK2_VIEW_NODE_TAB structure, then based on the amount of +// views in the tab selects the correct substructure and adds an avkon +// tab from the TAB resource +// -------------------------------------------------------------------------- +// +void CPbk2TabGroupContainer::DoReadViewNodeTabResourcesL + ( const CPbk2ViewNode& aNode, CAknTabGroup& aAknTabGroup, + TInt aViewCount ) + { + // Reads PBK2_VIEW_NODE_TAB structure in the + // view graph node + TResourceReader resReader; + CCoeEnv::Static()->CreateResourceReaderLC + ( resReader, aNode.TabResourceId() ); + + // Check how many PBK2_VIEW_NODE_TAB elements there are to read + const TInt count = resReader.ReadInt16(); + TBool found = EFalse; + // Loop through the resource elements, + for ( TInt i = 0; i < count && !found; ++i ) + { + resReader.ReadInt8(); // read version number + TInt tabsInGroup = resReader.ReadInt8(); + TInt tabResourceId = resReader.ReadInt32(); + TInt iconResId = resReader.ReadInt32(); + // Check if this resource structure corresponds + // to the amount of tabs previously found in the tab group + if ( tabsInGroup == aViewCount || + (aViewCount >= KMaxTabsInTabGroup && + tabsInGroup == KMaxTabsInTabGroup)) + { + // Read a TAB structure + TResourceReader tabResReader; + CCoeEnv::Static()->CreateResourceReaderLC + ( tabResReader, tabResourceId ); + // Feed structure to Avkon tab group + aAknTabGroup.AddTabL( tabResReader ); + CleanupStack::PopAndDestroy(); // tabResReader + + // Read the icons + if ( iconResId != 0 ) + { + // Add icon infos associated with the TAB to the + // icon info container + iTabIcons->AppendIconsFromResourceL( + iconResId ); + } + } + } + CleanupStack::PopAndDestroy(); // resReader + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::CreateTabGroupsL +// Initializes the tab group from the view graph +// -------------------------------------------------------------------------- +// +void CPbk2TabGroupContainer::CreateTabGroupsL() + { + RArray viewIds; + CleanupClosePushL( viewIds ); + + // Get the number of nodes in the view graph + const TInt nodeCount = iViewExplorer.ViewGraph().Count(); + + // Travel through all the view graph nodes + for ( TInt i = 0; i < nodeCount; ++i ) + { + const CPbk2ViewNode& viewNode = iViewExplorer.ViewGraph()[i]; + + // Check the view nodes tab group id and if it exists with + // tab resource id, create tabs unless the view has already + // been added to some tab group + TPbk2TabGroupId tabGroupId = viewNode.TabGroupId(); + if ( tabGroupId != 0 && + viewNode.TabResourceId() != 0 && + viewIds.Find( viewNode.ViewId() ) == KErrNotFound ) + { + // Get the view graph nodes in the same tab group + RPointerArray viewsInTabGroup = + iViewExplorer.ViewGraph().FindViewsInTabGroupL( + tabGroupId ); + CleanupClosePushL( viewsInTabGroup ); + + // Set up the tab group width + const TInt viewsInTabGroupCount = viewsInTabGroup.Count(); + const TInt tabWidth = + DoCalculateTabGroupWidth( viewsInTabGroupCount ); + + // Create tab group if it does not already exist + CAknTabGroup& aknTabGroup = FindTabGroupWithIdL( tabGroupId ); + aknTabGroup.SetTabFixedWidthL( tabWidth ); + + // Loop through the tab groups' views + for ( TInt view = 0; view < viewsInTabGroupCount; ++view ) + { + // Get the tab group view node and add its view id to + // the view id array + const CPbk2ViewNode& node = *viewsInTabGroup[view]; + viewIds.AppendL( node.ViewId() ); + + // If there is no tabs TabResourceId() returns 0. + // tabs -resource defaults to 0. + if (node.TabResourceId() != 0) + { + // Read the view node tab resource structure and + // adds the tabs to the tab group + DoReadViewNodeTabResourcesL + ( node, aknTabGroup, viewsInTabGroupCount ); + } + else + { + // tab group resource doesnt exits, ask callback to create tab + iCallback.CreateViewNodeTabL( + node, aknTabGroup, *iTabIcons, viewsInTabGroupCount ); + } + + } + CleanupStack::PopAndDestroy(); // viewInTabGroup + } + } + CleanupStack::PopAndDestroy(); // viewIds + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::FindTabGroupWithIdL +// -------------------------------------------------------------------------- +// +CAknTabGroup& CPbk2TabGroupContainer::FindTabGroupWithIdL + ( TPbk2TabGroupId aTabGroupId ) + { + CAknTabGroup* result = NULL; + + // Find the tab group from the container + const TInt tabGroupCount = iViewTabGroups.Count(); + for ( TInt i=0; i < tabGroupCount; ++i ) + { + if ( iViewTabGroups[i]->TabGroupId() == aTabGroupId ) + { + result = iViewTabGroups[i]->TabGroup(); + break; + } + } + + // If the tab group doesnt exists, it is created + if ( !result ) + { + CAknNavigationControlContainer* naviPane = + static_cast + ( CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL + ( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + + // Create the new tab group + CAknNavigationDecorator* newTabGroup = + naviPane->CreateTabGroupL( this ); + CleanupStack::PushL( newTabGroup ); + CPbk2TabGroupEntry* entry = CPbk2TabGroupEntry::NewL + ( aTabGroupId, newTabGroup ); + CleanupStack::Pop( newTabGroup ); + CleanupStack::PushL(entry); + iViewTabGroups.AppendL(entry); + CleanupStack::Pop( entry ); + result = static_cast + ( newTabGroup->DecoratedControl() ); + } + + return *result; + } + +// -------------------------------------------------------------------------- +// CPbk2TabGroupContainer::SkinTabGroupsL +// This function loops all the tabs and overrides then if theres a skin +// -------------------------------------------------------------------------- +// +void CPbk2TabGroupContainer::SkinTabGroupsL() + { + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + + // Travel all the tab groups that have been created + const TInt count = iViewTabGroups.Count(); + for (TInt i = 0; i < count; ++i) + { + CAknTabGroup& tabGroup = *iViewTabGroups[i]->TabGroup(); + + // loop through the tabs in the tab group + const TInt tabCount = tabGroup.TabCount(); + for (TInt j = 0; j < tabCount; ++j) + { + TInt tabId = tabGroup.TabIdFromIndex(j); + // tabId is used as icon id + TPbk2IconId iconId( TUid::Uid(KPbk2UID3), tabId ); + // Find the icon info from the tab icon info container + const CPbk2IconInfo* iconInfo = iTabIcons->Find(iconId); + if (iconInfo) + { + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + CPbk2IconFactory* factory = + CPbk2IconFactory::NewLC( *iTabIcons ); + // Load the icon and mask + factory->CreateIconLC(iconId, *skin, bitmap, mask); + // Replace tab with new bitmaps, skin enabled + tabGroup.ReplaceTabL(tabId, bitmap, mask); + CleanupStack::Pop(2); // mask, bitmap + CleanupStack::PopAndDestroy(factory); + } + } + } + } + +// End of File