--- /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 <eikfutil.h>
+#include <eikappui.h>
+#include <eikapp.h>
+
+#include <apgcli.h>
+#include <apgicnfl.h>
+#include <apgwgnam.h>
+
+#include <gulicon.h>
+#include <gulutil.h>
+#include <eikimage.h>
+
+#include <AknIconUtils.h>
+
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+
+#include <AknTasHook.h>
+#include "AknPanic.h"
+#include "AknUtils.h"
+#include "aknconsts.h"
+#include "akncontext.h"
+
+#include <avkon.mbg>
+#include <eikspane.h>
+
+#include "aknnavi.h"
+#include "AknBitmapMirrorUtils.h"
+#include "AknNaviConstants.h"
+#include "aknappui.h"
+#include <AknDef.h>
+
+
+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<RWsSession::TWindowGroupChainInfo>* aWgIds )
+ {
+ // Go through all window group IDs looking for the current one
+ for (TInt i=0;i<aCount;i++)
+ {
+ RWsSession::TWindowGroupChainInfo wgId=(*aWgIds)[i];
+
+ if ( wgId.iId == aWgId ) // found my wg
+ {
+ if (wgId.iParentId <= 0) // I'm standalone application
+ break;
+ else
+ {
+ aWgId = wgId.iParentId;
+ FindRootApplication(aCount, aWgId, aWgIds);
+ }
+ }
+ }
+
+ }
+
+
+EXPORT_C void CAknContextPane::SetPictureToDefaultL()
+ {
+ if (iExtension->iDefaultContextImage)
+ {
+ 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<RWsSession::TWindowGroupChainInfo>* wgIds=new(ELeave) RArray<RWsSession::TWindowGroupChainInfo>(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<CFbsBitmap*>( iExtension->iContextImage->Bitmap() ),
+ layoutRect.Rect().Size());
+
+ if ( sameIcons )
+ {
+ // Must duplicate again after SetSize.
+ CFbsBitmap* bitmap = const_cast<CFbsBitmap*>(
+ iExtension->iDefaultContextImage->Bitmap() );
+ CFbsBitmap* mask = const_cast<CFbsBitmap*>(
+ 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
+
+