diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/akncontext.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/akncontext.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,652 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +// INCLUDE FILES +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include "AknPanic.h" +#include "AknUtils.h" +#include "aknconsts.h" +#include "akncontext.h" + +#include +#include + +#include "aknnavi.h" +#include "AknBitmapMirrorUtils.h" +#include "AknNaviConstants.h" +#include "aknappui.h" +#include + + +NONSHARABLE_CLASS(CAknContextPaneExtension): public CBase + { +public: + CAknContextPaneExtension(); + ~CAknContextPaneExtension(); +public: + CEikImage* iContextImage; + CEikImage* iDefaultContextImage; + TInt iCurrentColorScheme; + }; + +CAknContextPaneExtension::CAknContextPaneExtension() + { + } + +CAknContextPaneExtension::~CAknContextPaneExtension() + { + } + +EXPORT_C CAknContextPane::CAknContextPane() + { + AKNTASHOOK_ADD( this, "CAknContextPane" ); + } + +EXPORT_C CAknContextPane::~CAknContextPane() + { + AKNTASHOOK_REMOVE(); + AknsUtils::DeregisterControlPosition( this ); + if (iExtension) + { + AknsUtils::DeregisterControlPosition( iExtension->iContextImage ); + AknsUtils::DeregisterControlPosition( iExtension->iDefaultContextImage ); + delete iExtension->iContextImage; + delete iExtension->iDefaultContextImage; + delete iExtension; + } + } + +EXPORT_C void CAknContextPane::ConstructL() + { + CommonConstructL(); + TRAP_IGNORE(SetPictureToDefaultL()); // Trapped because of Java midlet issues + } + + +EXPORT_C void CAknContextPane::ConstructFromResourceL(TResourceReader& aReader) + { + CommonConstructL(); + ReadFromResourceFileL(aReader); + } + +EXPORT_C void CAknContextPane::SetPicture(const CFbsBitmap* aBitmap, const CFbsBitmap* aMaskBitmap) + { + TBool bitmapChanged = EFalse; + if (iExtension->iContextImage) + { + bitmapChanged = ETrue; + iExtension->iContextImage->SetPictureOwnedExternally(EFalse); + iExtension->iContextImage->SetPicture(aBitmap, aMaskBitmap); + } + else + { + // Try to create new iContextImage object. + TRAPD( error, InitL() ); + if ( !error ) + { + bitmapChanged = ETrue; + iExtension->iContextImage->SetPictureOwnedExternally(EFalse); + iExtension->iContextImage->SetPicture(aBitmap, aMaskBitmap); + } + else + { + // Ownership taken - delete if there is not memory to create new iContextImage. + delete aBitmap; + delete aMaskBitmap; + } + } + + if ( bitmapChanged ) + { + SizeChanged(); + DrawNow(); + } + } + +EXPORT_C void CAknContextPane::SetPicture(CEikImage* aImage) + { + __ASSERT_ALWAYS(aImage && aImage->Bitmap(), Panic(EAknPanicNullPointer)); + + delete iExtension->iContextImage; + iExtension->iContextImage = aImage; + if (!iExtension->iContextImage->DrawableWindow()) + { + TRAP_IGNORE(iExtension->iContextImage->SetContainerWindowL(*this)); + } + __ASSERT_DEBUG(iExtension->iContextImage->DrawableWindow(), Panic(EAknPanicNullPointer)); + + iExtension->iContextImage->SetPictureOwnedExternally(EFalse); + + SizeChanged(); + DrawNow(); + } + +EXPORT_C void CAknContextPane::SetPictureFromFileL(const TDesC& aFileName, TInt aMainId, TInt aMaskId) + { + delete iExtension->iContextImage; + iExtension->iContextImage = NULL; + + InitL(); + iExtension->iContextImage->CreatePictureFromFileL(aFileName, aMainId, aMaskId); + + SizeChanged(); + DrawNow(); + } + + +EXPORT_C void CAknContextPane::SetFromResourceL(TResourceReader& aReader) + { + ReadFromResourceFileL(aReader); + } + + +void FindRootApplication(TInt aCount, TInt& aWgId, RArray* aWgIds ) + { + // Go through all window group IDs looking for the current one + for (TInt i=0;iiDefaultContextImage) + { + CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(bitmap); + CFbsBitmap* mask = new (ELeave) CFbsBitmap(); + + if ( iExtension->iDefaultContextImage->Bitmap() ) + { + bitmap->Duplicate(iExtension->iDefaultContextImage->Bitmap()->Handle()); + } + if ( iExtension->iDefaultContextImage->Mask() ) + { + mask->Duplicate(iExtension->iDefaultContextImage->Mask()->Handle()); + } + SetPicture(bitmap, mask); + CleanupStack::Pop(); // bitmap + return; + } + + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + + // statuspane + TAknLayoutRect statuspane; + statuspane.LayoutRect(iAvkonAppUi->ApplicationRect(), AknLayout::status_pane(iAvkonAppUi->ApplicationRect(),0)); + + // context pane + TAknWindowLineLayout contextPaneLayout = AknLayout::context_pane(statuspane.Rect(), 0); + TAknLayoutRect contextPaneLayoutRect; + contextPaneLayoutRect.LayoutRect(statuspane.Rect(), contextPaneLayout); + TRect contextPaneRect = contextPaneLayoutRect.Rect(); + + // context pane elements + TAknWindowLineLayout contextPaneElements = + AknLayout::Context_pane_elements_Line_1(); + TAknLayoutRect rect; + rect.LayoutRect(contextPaneRect, contextPaneElements); + + // -- Wg chaining support --- + RWsSession& ws = iEikonEnv->WsSession(); + + TInt wgCount=ws.NumWindowGroups(); + TInt wgId = iEikonEnv->RootWin().Identifier(); + + RArray* wgIds=new(ELeave) RArray(wgCount); + CleanupStack::PushL(wgIds); + CleanupClosePushL(*wgIds); + + User::LeaveIfError(ws.WindowGroupList(wgIds)); + + FindRootApplication(wgCount, wgId, wgIds ); + + CleanupStack::PopAndDestroy(2); // wgids + + CApaWindowGroupName* windowName = CApaWindowGroupName::NewLC(ws, wgId); + TUid appUid = windowName->AppUid(); + CleanupStack::PopAndDestroy(); //windowName + + // ------ + + AknsUtils::CreateAppIconLC( AknsUtils::SkinInstance(), + appUid, EAknsAppIconTypeContext, + bitmap, mask ); + + SetPictureSize( bitmap, + rect.Rect().Size() ) ; + + iExtension->iDefaultContextImage = new (ELeave) CEikImage; + CFbsBitmap* defaultBitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(defaultBitmap); + CFbsBitmap* defaultMask = new (ELeave) CFbsBitmap(); + defaultBitmap->Duplicate(bitmap->Handle()); + defaultMask->Duplicate(mask->Handle()); + iExtension->iDefaultContextImage->SetPicture(defaultBitmap, defaultMask); + iExtension->iDefaultContextImage->SetPictureOwnedExternally(EFalse); + + // ownership of the defaultBitmap moved to iDefaultContextImage. + CleanupStack::Pop( 3 ); // defaultBitmap, mask, bitmap + SetPicture( bitmap, mask ); + } + +EXPORT_C const CEikImage& CAknContextPane::Picture() const + { + return *(iExtension->iContextImage); + } + +EXPORT_C CEikImage* CAknContextPane::SwapPicture(CEikImage* aNewImage) + { + CEikImage* previousImage = iExtension->iContextImage; + iExtension->iContextImage = aNewImage; + if (iExtension->iContextImage) + { + if (!iExtension->iContextImage->DrawableWindow()) + { + TRAP_IGNORE( iExtension->iContextImage->SetContainerWindowL(*this) ); + } + + __ASSERT_DEBUG(iExtension->iContextImage->DrawableWindow(), Panic(EAknPanicNullPointer)); + + iExtension->iContextImage->SetPictureOwnedExternally(EFalse); + } + SizeChanged(); + DrawNow(); + + return previousImage; + } + + +EXPORT_C void CAknContextPane::SizeChanged() + { + if (Rect() != TRect(0,0,0,0)) // Fix for Parent getting parent relative data. + { + if (iExtension->iContextImage && iExtension->iContextImage->Bitmap()) + { + TAknLayoutRect layoutRect; + layoutRect.LayoutRect(Rect(), AknLayout::Context_pane_elements_Line_1()); + + TBool sameIcons = EFalse; + + if ( iExtension->iDefaultContextImage && + iExtension->iDefaultContextImage->Bitmap() && + iExtension->iDefaultContextImage->Bitmap()->Handle() == + iExtension->iContextImage->Bitmap()->Handle() ) + { + sameIcons = ETrue; + } + + // This potentially changes bitmap handles. + SetPictureSize( const_cast( iExtension->iContextImage->Bitmap() ), + layoutRect.Rect().Size()); + + if ( sameIcons ) + { + // Must duplicate again after SetSize. + CFbsBitmap* bitmap = const_cast( + iExtension->iDefaultContextImage->Bitmap() ); + CFbsBitmap* mask = const_cast( + iExtension->iDefaultContextImage->Mask() ); + + if ( bitmap ) + { + // ignore error + bitmap->Duplicate( iExtension->iContextImage->Bitmap()->Handle() ); + } + + if ( mask ) + { + // ignore error + mask->Duplicate( iExtension->iContextImage->Mask()->Handle() ); + } + } + + TSize bmpSize=iExtension->iContextImage->Bitmap()->SizeInPixels(); + TGulAlignment iAlignment; + iAlignment.SetHAlignment(EHCenter); + iAlignment.SetVAlignment(EVCenter); + iExtension->iContextImage->SetRect(iAlignment.InnerRect(Rect(),bmpSize)); + AknsUtils::RegisterControlPosition( iExtension->iContextImage ); + } + AknsUtils::RegisterControlPosition( this ); + } + } + + +EXPORT_C void CAknContextPane::HandleResourceChange( TInt aType ) + { + if ( aType == KEikColorResourceChange || aType==KEikDynamicLayoutVariantSwitch ) + { + DrawDeferred(); + } + else if( aType == KAknsMessageSkinChange ) + { + if( iExtension->iDefaultContextImage && iExtension->iContextImage ) + { + const CFbsBitmap* defBmp = iExtension->iDefaultContextImage->Bitmap(); + const CFbsBitmap* bmp = iExtension->iContextImage->Bitmap(); + if( defBmp && bmp ) + { + // Update icon only if the default context image is used. + // Otherwise, the application is responsible of updating the + // image upon skin change (since it has set a non-default image). + if( defBmp->Handle() == bmp->Handle() ) + { + delete iExtension->iDefaultContextImage; + iExtension->iDefaultContextImage = NULL; + TRAP_IGNORE(SetPictureToDefaultL()); // Ignore error + } + } + } + } + } + + +EXPORT_C TInt CAknContextPane::CountComponentControls() const + { + if (iExtension->iContextImage) + { + return 1; + } + return 0; + } + + +EXPORT_C CCoeControl* CAknContextPane::ComponentControl(TInt /*aIndex*/) const + { + return (iExtension->iContextImage); + } + + +EXPORT_C void CAknContextPane::Draw(const TRect& /*aRect*/) const + { + CWindowGc& gc=SystemGc(); + + // screen + TRect screenRect = iAvkonAppUi->ApplicationRect(); + + //TAknWindowLineLayout screenLayout = AknLayout::screen(); + //TRect screenRect = screenLayout.Rect(); + + + // app window + TAknWindowLineLayout applicationWindowLayout = + AknLayout::application_window(screenRect); + + TAknLayoutRect applicationWindowLayoutRect; + applicationWindowLayoutRect.LayoutRect(screenRect, applicationWindowLayout); + TRect applicationWindowRect = applicationWindowLayoutRect.Rect(); + + // statuspane + TAknWindowLineLayout statusPaneLayout = + AknLayout::status_pane(applicationWindowRect, 0); + + TAknLayoutRect statusPaneLayoutRect; + statusPaneLayoutRect.LayoutRect(applicationWindowRect, statusPaneLayout); + TRect statusPaneRect = statusPaneLayoutRect.Rect(); + + // context pane + TAknWindowLineLayout contextPaneLayout = + AknLayout::context_pane(statusPaneRect, 0); + + TAknLayoutRect contextPaneLayoutRect; + contextPaneLayoutRect.LayoutRect(statusPaneRect, contextPaneLayout); + TRect contextPaneRect = contextPaneLayoutRect.Rect(); + + TAknWindowLineLayout naviPaneGraphicsLayout = + AknLayout::Status_pane_elements_Line_1(); + + TAknWindowLineLayout naviWipeGraphicsLayout = + AknLayout::Status_pane_elements_Line_2(); + + TAknLayoutRect naviPaneGraphicsLayoutRect; + naviPaneGraphicsLayoutRect.LayoutRect(statusPaneRect, naviPaneGraphicsLayout); + TRect naviPaneGraphicsRect = naviPaneGraphicsLayoutRect.Rect(); + + TAknLayoutRect naviWipeGraphicsLayoutRect; + naviWipeGraphicsLayoutRect.LayoutRect(statusPaneRect, naviWipeGraphicsLayout); + TRect naviWipeGraphicsRect = naviWipeGraphicsLayoutRect.Rect(); + + TRect rect(Rect()); + + TRect barRect = contextPaneRect; + if (barRect.Intersects(naviPaneGraphicsRect)) + { + barRect.Intersection(naviPaneGraphicsRect); + + // calculate new origo, relative to context pane. + barRect.iTl.iX -= contextPaneRect.iTl.iX; + barRect.iTl.iY -= contextPaneRect.iTl.iY; + barRect.iBr.iX -= contextPaneRect.iTl.iX; + barRect.iBr.iY -= contextPaneRect.iTl.iY; + } + else + { + barRect = TRect(0,0,0,0); + } + + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext(this); + + // Solid or wipe comes from background + if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) ) + { + // Default drawing if skinning is not available + gc.Clear(rect); + gc.SetPenStyle(CGraphicsContext::ENullPen); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetBrushColor(AKN_LAF_COLOR(KStatusPaneBackgroundGraphicsColorUsual)); + gc.DrawRect(barRect); + } + } + + +void CAknContextPane::CommonConstructL() + { + InitL(); + // Wipe is never used initally anymore + SetNaviPaneBackgroundType( EAknNaviPaneBackgroundTypeSolid ); + } + + +TUid CAknContextPane::AppUid() + { + // Returns application's Uid. + // In embedded applications, root application's Uid is returned. + CEikAppUi* root = iEikonEnv->EikAppUi(); + while (root->ContainerAppUi()) + { + root = root->ContainerAppUi(); + } + + CEikApplication* app = root->Application(); + if (app) + { + return app->AppDllUid(); + } + return KNullUid; + } + + +void CAknContextPane::ReadFromResourceFileL(TResourceReader& aReader) + { + HBufC* bitmapFile = aReader.ReadHBufCL(); // bmp filename + TInt bitmapId = aReader.ReadInt16(); // bmp id + TInt maskId = aReader.ReadInt16(); // bmp mask id + + if ( bitmapFile ) + { + CleanupStack::PushL(bitmapFile); + if (bitmapId != -1) + { + SetPictureFromFileL(*bitmapFile, bitmapId, maskId); + } + CleanupStack::PopAndDestroy(); // bitmapFile + } + else + { + TRAP_IGNORE(SetPictureToDefaultL()); // Trapped because of Java midlet issues + } + } + +void CAknContextPane::LoadNaviWipeBitmapL() + { + // Naviwipe is no more used (since 3.0) + } + +void CAknContextPane::SetNaviPaneBackgroundType( TInt /*aType*/ ) + { + // Naviwipe is no more used (since 3.0) + } + +EXPORT_C void CAknContextPane::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + CAknControl::HandlePointerEventL(aPointerEvent); + } + +EXPORT_C void* CAknContextPane::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +TTypeUid::Ptr CAknContextPane::MopSupplyObject(TTypeUid aId) + { + if(aId.iUid == CAknContextPane::ETypeId) + { + // Return self, this code makes it possible to workaround the fact + // that statuspane controls cannot be safely casted after + // retrieving them using CEikStatusPaneBase::ControlL(). + // + // So now the caller could do something like this rather safely: + // + // CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + // CAknContextPane* contextPane = NULL; + // + //if (statusPane && + // statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidContext)).IsInCurrentLayout()) + // { + // CCoeControl* control = statusPane->ControlL(TUid::Uid( EEikStatusPaneUidContext )); + // control->MopGetObject(contextPane); + // } + // + //if (contextPane) + // { + // // The retrieved control was type of CAknContextPane + // } + //else + // { + // // The retrieved control was NOT type of CAknContextPane. + // // Someone has perhaps swap the control in the statuspane. + // } + return aId.MakePtr(this); + } + + return CCoeControl::MopSupplyObject(aId); + } + +void CAknContextPane::InitL() + { + if (!iExtension) + { + iExtension = new (ELeave) CAknContextPaneExtension(); + } + iExtension->iContextImage = new (ELeave) CEikImage; + iExtension->iContextImage->SetContainerWindowL(*this); + __ASSERT_DEBUG(iExtension->iContextImage->DrawableWindow(), Panic(EAknPanicNullPointer)); + iExtension->iContextImage->SetNonFocusing(); + iExtension->iContextImage->SetAlignment(EHCenterVCenter); + } + +void CAknContextPane::SetPictureSize(CFbsBitmap* aPicture, TSize aSize) + { + const TSize KLegacyScreenSize = TSize(176,208); + const TSize KLegacyPictureMaxSize = TSize(44,44); + + if (!aPicture) + return; + + TRect screenRect = iAvkonAppUi->ApplicationRect(); + TSize originalSize = aPicture->SizeInPixels(); + + TBool isLegacyScreenSize = + (screenRect.Height() == KLegacyScreenSize.iHeight && + screenRect.Width() == KLegacyScreenSize.iWidth); + + TBool isBitmap = !AknIconUtils::IsMifIcon(aPicture); + + TBool isBitmapValidLegacySize = + (originalSize.iHeight <= KLegacyPictureMaxSize.iHeight && + originalSize.iWidth <= KLegacyPictureMaxSize.iWidth); + + // If we are in legacy screen size and the given bitmap is bitmap (not SVG originated) + // and its size is ok we don't set the size. This is done because + // some legacy app have contextpane icons sizes other than + // 44x44 and those look better if left not scaled. + if (isLegacyScreenSize && + isBitmap && + isBitmapValidLegacySize) + { + return; + } + + // Perf optimization: We dont set the size if context pane is not in current status pane layout. When + // status pane layout changes, this method will be called again and size is set then. + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + if (statusPane && statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidContext)).IsInCurrentLayout()) + { + AknIconUtils::SetSize( aPicture, aSize); + } + } + + +// End of File + +