--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluirendering/renderingplugins/xnmenufactory/src/xnmenuadapter.cpp Wed Sep 01 12:32:46 2010 +0100
@@ -0,0 +1,2848 @@
+/*
+* Copyright (c) 2002-2004 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: Implementation for wrapper for a menu
+*
+*/
+
+// System includes
+#include <utf.h>
+#include <aknappui.h>
+#include <e32base.h>
+#include <coecntrl.h>
+#include <eikbtgpc.h>
+#include <eikcba.h>
+#include <barsread.h>
+#include <eiksoftkeyimage.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <layoutmetadata.cdl.h>
+
+#include <AknStatuspaneUtils.h>
+#include <AknUtils.h>
+#include <AknIconUtils.h>
+#include <eikspane.h>
+#include <AknSgcc.h>
+#include <aknview.h>
+#include <AknsConstants.h>
+
+// User includes
+#include "xnnodepluginif.h"
+#include "xntype.h"
+#include "xnproperty.h"
+
+#include "xndompropertyvalue.h"
+#include "xndomproperty.h"
+#include "xndomlist.h"
+
+#include "xnuienginepluginif.h"
+#include "xncomponent.h"
+
+#include "xnappuiadapter.h"
+#include "xnbitmap.h"
+#include "xnmenuadapter.h"
+#include "xncomponentnodeimpl.h"
+#include "c_xnutils.h"
+
+#undef _AVKON_CBA_LSC
+
+_LIT8( KEditMode, "Menu/EditMode" );
+_LIT8( KNormalMode, "Menu/NormalMode" );
+_LIT8( KContextEditMode, "ContextMenu/EditMode" );
+_LIT8( KContextNormalMode, "ContextMenu/NormalMode" );
+_LIT8( KAlwaysShown, "Menu/AlwaysShown" );
+
+_LIT8( KHsShowHelp, "hs_show_help" );
+
+const TInt KMenuCommandFirst = 6000;
+const TInt KMenuCommandLast = 6199;
+const TInt KCBACommandFirst = EAknSoftkeyOptions;
+const TInt KCBACommandSecond = EAknSoftkeyBack;
+const TInt KCBACommandMiddle = EAknSoftkeyDialler;
+
+const TInt KXnMenuArrayGranularity = 6;
+const TInt KWideScreenWidth = 640;
+
+using namespace XnPropertyNames;
+
+static CXnNodePluginIf* FindChildL(CXnNodePluginIf& aNode,
+ const TDesC8& aType, const TDesC8& aTarget = KNullDesC8);
+
+class CXnSoftkeyItem: public CBase
+ {
+public:
+ CXnSoftkeyItem()
+ : iNode( NULL ),
+ iPosition( 0 ),
+ iCommandId( 0 ),
+ iLabel( NULL ),
+ iBitmap( NULL ),
+ iMask( NULL ),
+ iImageOn( EFalse ),
+ iInvertMask( EFalse ),
+ iPreserveAspectRatio( EFalse ),
+ iUpdateAppearance( ETrue ),
+ iOwnBitmaps( ETrue ),
+ iDefault( EFalse ),
+ iId( KAknsIIDQsnIconColors ),
+ iBmpFile( NULL ),
+ iBmp( 0 ),
+ iBmpM( 0 )
+ {
+ }
+
+ ~CXnSoftkeyItem()
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ delete iLabel;
+ iLabel = NULL;
+ if ( iOwnBitmaps )
+ {
+ delete iBitmap;
+ iBitmap = NULL;
+ delete iMask;
+ iMask = NULL;
+ }
+ else
+ {
+ iBitmap = NULL;
+ iMask = NULL;
+ }
+
+ iImageOn = EFalse;
+ iInvertMask = EFalse;
+ iPreserveAspectRatio = EFalse;
+ delete iBmpFile;
+ iBmpFile = NULL;
+ }
+
+ CXnNodePluginIf* iNode;
+ TInt iPosition;
+ TInt iCommandId;
+ HBufC* iLabel;
+ CFbsBitmap* iBitmap;
+ CFbsBitmap* iMask;
+ TBool iImageOn;
+ TBool iInvertMask;
+ TBool iPreserveAspectRatio;
+ TBool iUpdateAppearance;
+ TBool iOwnBitmaps;
+ TBool iDefault;
+ TAknsItemID iId;
+ HBufC* iBmpFile;
+ TInt32 iBmp;
+ TInt32 iBmpM;
+ };
+
+
+inline TAknWindowComponentLayout DoCompose( TAknWindowComponentLayout aLine1,
+ TAknWindowComponentLayout aLine2 )
+ {
+ return TAknWindowComponentLayout::Compose( aLine1, aLine2 );
+ }
+
+inline TAknTextComponentLayout DoComposeText( TAknWindowComponentLayout aLine1,
+ TAknTextComponentLayout aLine2 )
+ {
+ return TAknWindowComponentLayout::ComposeText( aLine1, aLine2 );
+ }
+
+// -----------------------------------------------------------------------------
+// IsNodeVisibleL
+//
+// -----------------------------------------------------------------------------
+//
+static TBool IsNodeVisibleL(CXnNodePluginIf& aNode)
+ {
+ CXnProperty* propVisibility = aNode.VisibilityL();
+
+ if( propVisibility )
+ {
+ const TDesC8& visibility = propVisibility->StringValue();
+
+ if( visibility == XnPropertyNames::style::common::visibility::KHidden )
+ {
+ return EFalse;
+ }
+ }
+
+ CXnProperty* propDisplay = aNode.DisplayL();
+
+ if( propDisplay )
+ {
+ const TDesC8& display = propDisplay->StringValue();
+
+ if( display == XnPropertyNames::style::common::display::KNone )
+ {
+ return EFalse;
+ }
+ }
+
+ CXnProperty* propDisabled = aNode.GetPropertyL( XnPropertyNames::common::KDisabled );
+
+ if( propDisabled )
+ {
+ const TDesC8& disabled = propDisabled->StringValue();
+
+ if( disabled == XnPropertyNames::KTrue )
+ {
+ return EFalse;
+ }
+ }
+
+ return ETrue;
+ }
+
+#ifdef _AVKON_CBA_LSC
+// -----------------------------------------------------------------------------
+//
+// Calculate touch sensitive softkey area for Top button (landscape)
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectTopTouch()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknLayoutRect layoutRect;
+
+ TAknWindowComponentLayout rightAreaLayout(
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+
+ layoutRect.LayoutRect( screen, DoCompose( rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane() ).LayoutLine() );
+ TRect topSKRect( layoutRect.Rect() );
+
+ layoutRect.LayoutRect( topSKRect,
+ AknLayoutScalable_Avkon::aid_touch_sctrl_top().LayoutLine() );
+ return layoutRect.Rect();
+ }
+
+// -----------------------------------------------------------------------------
+//
+// Calculate touch sensitive softkey area for right button (portrait)
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectRightTouch()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknLayoutRect layoutRect;
+
+ TAknWindowComponentLayout bottomAreaLayout(
+ AknLayoutScalable_Avkon::area_bottom_pane( 0 ) );
+
+
+ layoutRect.LayoutRect( screen, DoCompose( bottomAreaLayout,
+ AknLayoutScalable_Avkon::control_bg_pane() ).LayoutLine() );
+ TRect rightSKRect( layoutRect.Rect() );
+ layoutRect.LayoutRect(
+ rightSKRect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() );
+ return layoutRect.Rect();
+ }
+
+// -----------------------------------------------------------------------------
+//
+// Calculate touch sensitive softkey area for left button (portrait)
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectLeftTouch()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknLayoutRect layoutRect;
+
+ TAknWindowComponentLayout bottomAreaLayout(
+ AknLayoutScalable_Avkon::area_bottom_pane( 0 ) );
+
+
+ layoutRect.LayoutRect( screen, DoCompose( bottomAreaLayout,
+ AknLayoutScalable_Avkon::control_bg_pane() ).LayoutLine() );
+ TRect leftSKRect( layoutRect.Rect() );
+ layoutRect.LayoutRect(
+ leftSKRect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_left().LayoutLine() );
+
+ return layoutRect.Rect();
+
+ }
+
+// -----------------------------------------------------------------------------
+//
+// Calculate touch sensitive softkey area for Bottom button (landscape)
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectBottomTouch()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknLayoutRect layoutRect;
+
+ TAknWindowComponentLayout rightAreaLayout( AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+ layoutRect.LayoutRect( screen, DoCompose( rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ).LayoutLine() );
+ TRect bottomSKRect( layoutRect.Rect() );
+
+ layoutRect.LayoutRect( bottomSKRect,
+ AknLayoutScalable_Avkon::aid_touch_sctrl_bottom().LayoutLine() );
+ return layoutRect.Rect();
+ }
+#endif
+// -----------------------------------------------------------------------------
+//
+// Calculate (whole) softkey area for Bottom button (landscape)
+// -----------------------------------------------------------------------------
+static TBool HDLayoutActive()
+ {
+ TInt resourceId = 0;
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+
+ if ( statusPane ) // Return the resource ID of app statuspane if it exists.
+ {
+ resourceId = statusPane->CurrentLayoutResId();
+ }
+ else // If this app does not have statuspane, then we ask the layout from AknCapServer.
+ {
+ resourceId = CAknSgcClient::CurrentStatuspaneResource();
+ }
+
+ TBool retVal = EFalse;
+
+ if ( Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ // Can be widescreen only in landscape orientation.
+ retVal = ( resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL ||
+ resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE ||
+ resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL_FLAT ||
+ resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT );
+ }
+
+ return retVal;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// Calculate softkey image graphics area for Bottom button (landscape)
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectBottomGraphics()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknWindowComponentLayout rightAreaLayout(
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+ TAknWindowComponentLayout bottomSKLayout(
+ DoCompose( rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ) );
+
+ // Calculate softkey rects.
+ // Left (bottom in landscape) softkey layout.
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( screen,
+ bottomSKLayout.LayoutLine() );
+ TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() );
+
+ // Calculate softkey image layout.
+ // Left (bottom in landscape) softkey layout.
+ TAknWindowLineLayout leftSoftkeyImageLayout(
+ DoCompose(
+ bottomSKLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane_g1() ).LayoutLine() );
+
+
+ TAknLayoutRect qgn_graf_sk_left;
+ qgn_graf_sk_left.LayoutRect( screen, leftSoftkeyImageLayout );
+
+ return qgn_graf_sk_left.Rect();
+ }
+
+// -----------------------------------------------------------------------------
+//
+// Calculate softkey image graphics area for Top button (landscape)
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectTopGraphics()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknWindowComponentLayout rightAreaLayout(
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+ TAknWindowComponentLayout topSKLayout(
+ DoCompose( rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane() ) );
+
+ // Calculate softkey rects.
+ // Right (top in landscape) softkey layout.
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( screen,
+ topSKLayout.LayoutLine() );
+ TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() );
+
+ // Left (bottom in landscape) softkey layout.
+ // Right (top in landscape) softkey layout.
+ TAknWindowLineLayout rightSoftkeyImageLayout(
+ DoCompose(
+ topSKLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane_g1() ).LayoutLine() );
+
+ TAknLayoutRect qgn_graf_sk_right;
+ qgn_graf_sk_right.LayoutRect( screen, rightSoftkeyImageLayout );
+ return qgn_graf_sk_right.Rect();
+ }
+
+
+// -----------------------------------------------------------------------------
+// SoftkeyRectL
+// Calculate soft key rect
+// -----------------------------------------------------------------------------
+static TRect SoftkeyRectL( CEikButtonGroupContainer& aContainer, TInt aPos, TBool aImageOn )
+ {
+ TRect rect;
+
+ if( AknStatuspaneUtils::StaconPaneActive() )
+ {
+ TInt variety( 0 );
+
+ if( AknStatuspaneUtils::StaconSoftKeysLeft() )
+ {
+ variety = 1;
+ }
+
+ TRect parentRect( iAvkonAppUi->ApplicationRect() );
+
+ switch( aPos )
+ {
+ case CEikButtonGroupContainer::ELeftSoftkeyPosition:
+ {
+ TAknWindowComponentLayout layout0( AknLayoutScalable_Avkon::area_bottom_pane( 2 ) );
+ TAknWindowComponentLayout layout1( AknLayoutScalable_Avkon::stacon_bottom_pane() );
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt bottomCbaVariety( variety );
+
+ if( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ bottomCbaVariety += 2;
+ }
+
+ TAknWindowComponentLayout layout2( AknLayoutScalable_Avkon::control_bottom_pane_stacon( bottomCbaVariety ) );
+
+ if( aImageOn )
+ {
+ // Icon layout
+ TAknWindowComponentLayout iconLayout( AknLayoutScalable_Avkon::control_bottom_pane_stacon_g1() );
+
+ TAknWindowComponentLayout lskIconLayout( DoCompose( layout0,
+ DoCompose( layout1, DoCompose( layout2, iconLayout ) ) ) );
+
+ TAknWindowLineLayout lskIcon( lskIconLayout.LayoutLine() );
+
+ TAknLayoutRect qgn_icon_lsk;
+
+ qgn_icon_lsk.LayoutRect( parentRect, lskIcon );
+
+ rect = qgn_icon_lsk.Rect();
+ }
+ else
+ {
+ // Text layout
+ TAknTextComponentLayout textLayout( AknLayoutScalable_Avkon::control_bottom_pane_stacon_t1( variety ) );
+
+ TAknTextComponentLayout lskTextLayout( DoComposeText( layout0,
+ DoComposeText( layout1, DoComposeText( layout2, textLayout ) ) ) );
+
+ TAknTextLineLayout lskText( lskTextLayout.LayoutLine() );
+
+ TAknLayoutText qgn_text_lsk;
+
+ qgn_text_lsk.LayoutText( parentRect, lskText );
+
+ rect = qgn_text_lsk.TextRect();
+ }
+ }
+ break;
+ case CEikButtonGroupContainer::ERightSoftkeyPosition:
+ {
+ TAknWindowComponentLayout layout0( AknLayoutScalable_Avkon::area_top_pane( 2 ) );
+ TAknWindowComponentLayout layout1( AknLayoutScalable_Avkon::stacon_top_pane() );
+
+ TInt topCbaVariety( variety );
+
+ if( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ topCbaVariety += 4;
+ }
+
+ TAknWindowComponentLayout layout2( AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety ) );
+
+ if( aImageOn )
+ {
+ // Icon layout
+ TAknWindowComponentLayout iconLayout( AknLayoutScalable_Avkon::control_top_pane_stacon_g1() );
+
+ TAknWindowComponentLayout rskIconLayout( DoCompose( layout0,
+ DoCompose( layout1, DoCompose( layout2, iconLayout ) ) ) );
+
+ TAknWindowLineLayout rskIcon( rskIconLayout.LayoutLine() );
+
+ TAknLayoutRect qgn_icon_rsk;
+
+ qgn_icon_rsk.LayoutRect( parentRect, rskIcon );
+
+ rect = qgn_icon_rsk.Rect();
+ }
+ else
+ {
+ // Text layout
+ TAknTextComponentLayout textLayout( AknLayoutScalable_Avkon::control_top_pane_stacon_t1( variety ) );
+
+ TAknTextComponentLayout rskTextLayout( DoComposeText( layout0,
+ DoComposeText( layout1, DoComposeText( layout2, textLayout ) ) ) );
+
+ TAknTextLineLayout rskText( rskTextLayout.LayoutLine() );
+
+ TAknLayoutText qgn_text_rsk;
+
+ qgn_text_rsk.LayoutText( parentRect, rskText );
+
+ rect = qgn_text_rsk.TextRect();
+ }
+ }
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ break;
+
+ }
+ }
+ else
+ {
+ TInt textVariety( 0 );
+ TInt graphVariety( 0 );
+
+ TBool mskEnabled( AknLayoutUtils::MSKEnabled() && Layout_Meta_Data::IsMSKEnabled() );
+
+ if ( mskEnabled )
+ {
+ textVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 3;
+ graphVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 4;
+ }
+ else
+ {
+ textVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 0;
+ graphVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 4;
+ }
+
+ CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) );
+
+ TRect parentRect( cba->Rect() );
+
+ switch( aPos )
+ {
+ case CEikButtonGroupContainer::ELeftSoftkeyPosition:
+ {
+ if( aImageOn )
+ {
+ if ( HDLayoutActive() &&
+ AKN_LAYOUT_WINDOW_screen.iW == KWideScreenWidth )
+ {
+ rect = SoftkeyRectBottomGraphics();
+ }
+ else
+ {
+
+ TAknLayoutRect qgn_icon_lsk;
+
+ qgn_icon_lsk.LayoutRect( parentRect,
+ AknLayoutScalable_Avkon::control_pane_g1( graphVariety ).LayoutLine() );
+
+ rect = qgn_icon_lsk.Rect();
+ }
+ }
+ else
+ {
+ TAknLayoutText qgn_text_lsk;
+
+ qgn_text_lsk.LayoutText( parentRect,
+ AknLayoutScalable_Avkon::control_pane_t1( textVariety ).LayoutLine() );
+
+ rect = qgn_text_lsk.TextRect();
+ }
+ }
+ break;
+ case CEikButtonGroupContainer::ERightSoftkeyPosition:
+ {
+ if( aImageOn )
+ {
+ if ( HDLayoutActive() &&
+ AKN_LAYOUT_WINDOW_screen.iW == KWideScreenWidth )
+ {
+ rect = SoftkeyRectTopGraphics();
+ }
+ else
+ {
+ TAknLayoutRect qgn_icon_rsk;
+
+ qgn_icon_rsk.LayoutRect( parentRect,
+ AknLayoutScalable_Avkon::control_pane_g2( graphVariety ).LayoutLine() );
+
+ rect = qgn_icon_rsk.Rect();
+ }
+ }
+ else
+ {
+ TAknLayoutText qgn_text_rsk;
+
+ qgn_text_rsk.LayoutText( parentRect,
+ AknLayoutScalable_Avkon::control_pane_t2( textVariety ).LayoutLine() );
+
+ rect = qgn_text_rsk.TextRect();
+ }
+ }
+ break;
+ case CEikButtonGroupContainer::EMiddleSoftkeyPosition:
+ {
+ if( !mskEnabled || aImageOn )
+ {
+ // No msk, or asking image size for msk
+ User::Leave( KErrNotSupported );
+ }
+ else
+ {
+ TAknLayoutText qgn_text_msk;
+
+ qgn_text_msk.LayoutText( parentRect,
+ AknLayoutScalable_Avkon::control_pane_t3( textVariety ).LayoutLine() );
+
+ rect = qgn_text_msk.TextRect();
+ }
+ }
+ break;
+ default:
+ User::Leave( KErrNotFound );
+ break;
+ }
+ }
+
+ return rect;
+ }
+// -----------------------------------------------------------------------------
+// Get softkey image rect
+// -----------------------------------------------------------------------------
+static TRect SoftkeyImageRect(CEikButtonGroupContainer& aContainer, TInt aPosition)
+ {
+ TRect ret;
+#ifndef _AVKON_CBA_LSC
+ TAknLayoutRect softkeyImg;
+ CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) );
+ TRect parentRect( cba->Rect() );
+
+ if(Layout_Meta_Data::IsLandscapeOrientation())
+ {
+ if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition)
+ {
+ TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g1(2);
+ softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() );
+ }
+ else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition)
+ {
+ TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g2(2);
+ softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() );
+ }
+ }
+ else
+ {
+ if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition)
+ {
+ TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g1(4);
+ softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() );
+ }
+ else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition)
+ {
+ TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g2(4);
+ softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() );
+
+ }
+ }
+ ret = softkeyImg.Rect();
+#else
+ if ( Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition)
+ {
+ ret = SoftkeyRectTopTouch();
+ }
+ else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition)
+ {
+ ret = SoftkeyRectBottomTouch();
+ }
+ }
+ else // portrait
+ {
+ if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition)
+ {
+ ret = SoftkeyRectLeftTouch();
+ }
+ else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition)
+ {
+ ret = SoftkeyRectRightTouch();
+ }
+ }
+#endif
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CopyBitmapLC
+// Copy bitmap
+// -----------------------------------------------------------------------------
+static CFbsBitmap* CopyBitmapL( const CFbsBitmap* aBitmap )
+ {
+ CFbsBitmap* copy = new ( ELeave ) CFbsBitmap;
+ CleanupStack::PushL( copy );
+
+ copy->Create( aBitmap->SizeInPixels(), aBitmap->DisplayMode() );
+
+ CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( copy );
+ CleanupStack::PushL( dev );
+
+ CFbsBitGc* gc = CFbsBitGc::NewL();
+ CleanupStack::PushL( gc );
+
+ gc->Activate( dev );
+ gc->BitBlt( TPoint( 0, 0 ), aBitmap );
+
+ CleanupStack::PopAndDestroy( 2 ); // gc, dev
+
+ CleanupStack::Pop( copy );
+
+ return copy;
+ }
+
+// -----------------------------------------------------------------------------
+// MenuTypeL
+// This is used to deactivate "active applications" menu item using the theme
+// Get the "menutype" property from menubar and check if it has value
+// "menuoptions" (default) or "menuoptionsnotaskswapper" and return
+// correct menu type.
+// -----------------------------------------------------------------------------
+static CEikMenuBar::TMenuType MenuTypeL( CXnNodePluginIf& aMenubarNode )
+ {
+ CEikMenuBar::TMenuType menuType( CEikMenuBar::EMenuOptions );
+
+ CXnProperty* property( aMenubarNode.GetPropertyL( XnPropertyNames::menu::KMenuType ) );
+
+ if( property )
+ {
+ if( property->StringValue() == XnPropertyNames::menu::menutype::KMenuOptionsNoTaskSwapper )
+ {
+ menuType = CEikMenuBar::EMenuOptionsNoTaskSwapper;
+ }
+ }
+
+ return menuType;
+ }
+
+// -----------------------------------------------------------------------------
+// FindChildL
+//
+// -----------------------------------------------------------------------------
+static CXnNodePluginIf* FindChildL( CXnNodePluginIf& aNode,
+ const TDesC8& aType, const TDesC8& aTarget )
+ {
+ RPointerArray<CXnNodePluginIf> children( aNode.ChildrenL() );
+ CleanupClosePushL( children );
+
+ CXnNodePluginIf* retval( NULL );
+
+ for( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNodePluginIf* child( children[i] );
+
+ if( child->Type()->Type() == aType )
+ {
+ if( aTarget == KNullDesC8 )
+ {
+ retval = child;
+ break;
+ }
+ else
+ {
+ CXnProperty* target( child->GetPropertyL( KXnTarget ) );
+
+ if( target && target->StringValue() == aTarget )
+ {
+ retval = child;
+ break;
+ }
+
+ CXnProperty* source( child->GetPropertyL( KXnSource ) );
+
+ if( source && source->StringValue() == aTarget )
+ {
+ retval = child;
+ break;
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &children );
+
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// FindWidgetElementL
+//
+// -----------------------------------------------------------------------------
+//
+static CXnNodePluginIf* FindWidgetElementL( CXnNodePluginIf& aPluginNode )
+ {
+ CXnNodePluginIf* retval( NULL );
+
+ RPointerArray< CXnNodePluginIf > children( aPluginNode.ChildrenL() );
+ CleanupClosePushL( children );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNodePluginIf* node( children[i] );
+
+ if ( node->AppIfL().InternalDomNodeType() == XnPropertyNames::KWidget )
+ {
+ retval = node;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &children );
+
+ return retval;
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::NewL
+// Symbian static 1st phase constructor
+// -----------------------------------------------------------------------------
+//
+CXnMenuAdapter* CXnMenuAdapter::NewL( CXnControlAdapter* aParent, CXnNodePluginIf& aNode )
+ {
+ CXnMenuAdapter* self = new( ELeave ) CXnMenuAdapter;
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aParent, aNode );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::ConstructL( CXnControlAdapter* /*aParent*/, CXnNodePluginIf& aNode )
+ {
+ iRootNode = &aNode;
+
+ CXnControlAdapter::ConstructL( aNode );
+
+ iUiEngine = iRootNode->UiEngineL();
+
+ CAknAppUi* appui( iAvkonAppUi );
+
+ iPreviousMenuPaneId = appui->StatusPane()->CurrentLayoutResId();
+
+ CEikMenuBar* current( iEikonEnv->AppUiFactory()->SwapMenuBar( NULL ) );
+ appui->RemoveFromStack( current );
+
+ delete current;
+ current = NULL;
+
+ InitSoftkeyItemsL();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::CXnMenuAdapter
+// C++ default constructor
+// -----------------------------------------------------------------------------
+//
+CXnMenuAdapter::CXnMenuAdapter():
+ iMenuItems( KXnMenuArrayGranularity ),
+ iIdCounter( KMenuCommandFirst )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::~CXnMenuAdapter
+// C++ destructor
+// -----------------------------------------------------------------------------
+//
+CXnMenuAdapter::~CXnMenuAdapter()
+ {
+ StopDisplayingMenu();
+
+ if ( iAvkonAppUi )
+ {
+ iAvkonAppUi->RemoveFromStack( iMenuBar );
+ }
+
+ if ( iMenuBar )
+ {
+ delete iMenuBar;
+ }
+
+ iSoftkeyItems.ResetAndDestroy();
+ iMenuItems.Reset();
+ }
+
+// -----------------------------------------------------------------------------
+// Create scaled bitmap from source bitmap.
+// -----------------------------------------------------------------------------
+//
+void CreateScaledBitmapL(
+ const TRect& aRect,
+ CFbsBitmap*& aTrgBitmap,
+ CFbsBitmap* aSrcBitmap,
+ TBool aPreserveAspectRatio )
+ {
+ TRect destRect = aRect;
+
+ if( aPreserveAspectRatio )
+ {
+ // Calculate the bitmap image dimensions so that it uses maximum space
+ // of the given rectangle and maintains aspect ratio.
+ TInt srcHeight = aSrcBitmap->SizeInPixels().iHeight;
+ TInt srcWidth = aSrcBitmap->SizeInPixels().iWidth;
+ TReal scaleRatio( 1 ); //no scale as defaul
+
+ // If any dimension is 0, then we do not bother to scale
+ if( aRect.Width() > 0 && aRect.Height() > 0 )
+ {
+ TReal xRatio = ( (TReal )srcWidth / ( TReal )aRect.Width() );
+ TReal yRatio = ( ( TReal )srcHeight / ( TReal )aRect.Height() );
+
+ //Find out appropriate scaling factor
+ xRatio > yRatio ? ( scaleRatio = xRatio ) : ( scaleRatio = yRatio );
+ }
+
+ // Scale the size for target bitmap
+ destRect.SetHeight( srcHeight / scaleRatio );
+ destRect.SetWidth( srcWidth / scaleRatio );
+ }
+
+ aTrgBitmap = new ( ELeave ) CFbsBitmap;
+ CleanupStack::PushL( aTrgBitmap );
+
+ // It is allowed to create zero height or width bitmap.
+ TInt err( aTrgBitmap->Create( destRect.Size(), aSrcBitmap->DisplayMode() ) );
+
+ if( err == KErrNone )
+ {
+ CXnUtils::ScaleBitmapL( destRect, aTrgBitmap, aSrcBitmap );
+ }
+
+ // we do not own the bitmap so just Pop.
+ CleanupStack::Pop( aTrgBitmap );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::PrepareSoftkeyImageL
+// Make a copy of originals and scale them to right size.
+// Finally place the scaled icon to right position of drawing area.
+// -----------------------------------------------------------------------------
+CEikImage* CXnMenuAdapter::PrepareSoftkeyImageL( const CXnSoftkeyItem& aItem, const TSize& aSize )
+ {
+ CFbsBitmap* bitmap( NULL );
+ CFbsBitmap* mask( NULL );
+
+ // Start from bitmap
+ CFbsBitmap* source( aItem.iBitmap );
+
+ TInt count( 0 );
+
+ // Go through bitmap and mask
+ for( TInt i = 0; i < 2; i++ )
+ {
+ if( !source )
+ {
+ source = aItem.iMask;
+ continue;
+ }
+
+ CFbsBitmap* scaled( NULL );
+
+ TScaleMode mode( aItem.iPreserveAspectRatio ? EAspectRatioPreserved : EAspectRatioNotPreserved );
+
+ if( AknIconUtils::IsMifIcon( source ) )
+ {
+ AknIconUtils::SetSize( source, aSize, mode );
+
+ scaled = CopyBitmapL( source );
+ }
+ else
+ {
+ CreateScaledBitmapL( TRect( aSize ), scaled, source, mode == EAspectRatioPreserved );
+ }
+
+ CleanupStack::PushL( scaled );
+
+ if( !aItem.iPreserveAspectRatio )
+ {
+ count++;
+
+ if( i == 0 )
+ {
+ bitmap = scaled;
+ }
+ else
+ {
+ mask = scaled;
+ }
+ }
+ else
+ {
+ CFbsBitmap* target = new ( ELeave ) CFbsBitmap;
+ CleanupStack::PushL( target );
+
+ // Target is size of whole draw area
+ User::LeaveIfError( target->Create( aSize, source->DisplayMode() ) );
+
+ CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( target );
+ CleanupStack::PushL( dev );
+
+ CFbsBitGc* gc = CFbsBitGc::NewL();
+ CleanupStack::PushL( gc );
+
+ gc->Activate( dev );
+
+ gc->SetBrushStyle( CGraphicsContext::ESolidBrush );
+ gc->SetPenStyle( CGraphicsContext::ENullPen );
+
+ if( aItem.iInvertMask )
+ {
+ // White, with full transparent alpha channel
+ gc->SetBrushColor( TRgb( 0x00FFFFFF, 0 ) );
+ }
+ else
+ {
+ // Black, with full transparent alpha channel
+ gc->SetBrushColor( TRgb( 0x00000000, 0 ) );
+ }
+
+ // Make whole target area transparent
+ gc->DrawRect( TRect( aSize ) );
+
+ TPoint iconPos;
+
+ switch( AknLayoutUtils::CbaLocation() )
+ {
+ case AknLayoutUtils::EAknCbaLocationBottom:
+ // Rsk must be moved to right, lsk is in correct place by default
+ if ( aItem.iPosition != CEikButtonGroupContainer::ELeftSoftkeyPosition )
+ {
+ iconPos.iX = aSize.iWidth - scaled->SizeInPixels().iWidth;
+ }
+ break;
+ case AknLayoutUtils::EAknCbaLocationRight:
+ // Rsk and lsk must be moved to right
+ iconPos.iX = aSize.iWidth - scaled->SizeInPixels().iWidth;
+ break;
+ case AknLayoutUtils::EAknCbaLocationLeft:
+ // Already in correct position
+ default:
+ break;
+ }
+
+ // Align horizontally to center
+ iconPos.iY = iconPos.iX ? 0 : ( ( aSize.iHeight - scaled->SizeInPixels().iHeight ) / 2 );
+
+ gc->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+ // Blit image to correct position
+ gc->BitBlt( iconPos, scaled );
+
+ CleanupStack::PopAndDestroy( 2, dev );
+
+ CleanupStack::Pop( target );
+
+ CleanupStack::PopAndDestroy( scaled );
+
+ CleanupStack::PushL( target );
+ count++;
+
+ if( i == 0 )
+ {
+ bitmap = target;
+ }
+ else
+ {
+ mask = target;
+ }
+
+
+ }
+
+ // Go with mask next
+ source = aItem.iMask;
+ }
+
+ // Takes ownership of scaled bitmap and mask
+ CEikImage* image = new ( ELeave ) CEikImage;
+
+ image->SetPictureOwnedExternally( EFalse );
+ image->SetPicture( bitmap, mask );
+
+ CleanupStack::Pop( count );
+
+ return image;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetSoftkeyAppearanceL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetSoftkeyAppearanceL( CXnSoftkeyItem& aItem )
+ {
+ if( iContainer && IsNodeVisibleL( *aItem.iNode) )
+ {
+ if( aItem.iImageOn )
+ {
+ ChangeSoftkeyImageL( aItem );
+ }
+ else if( aItem.iLabel )// change label
+ {
+ if ( aItem.iPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition )
+ {
+ EikSoftkeyImage::SetLabel( iContainer, ETrue );
+ }
+ else if ( aItem.iPosition == CEikButtonGroupContainer::ERightSoftkeyPosition )
+ {
+ EikSoftkeyImage::SetLabel( iContainer, EFalse );
+ }
+
+ iContainer->SetCommandL( aItem.iPosition, aItem.iCommandId, *aItem.iLabel );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::InitSoftkeyItemsL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::InitSoftkeyItemsL()
+ {
+ // No layout calulations needed
+ iRootNode->SetLayoutCapable( EFalse );
+
+ // create softkeyitems to hold data
+
+ RPointerArray< CXnNodePluginIf > children( iRootNode->ChildrenL() );
+ CleanupClosePushL( children );
+ CXnSoftkeyItem* item(0);
+ for(TInt i=0;i<children.Count();++i)
+ {
+ if(children[i]->Type()->Type() == XnPropertyNames::softkey::KNodeName)
+ {
+ item = AppendSoftkeyItemL(children[i]);
+ if(item)
+ {
+ item->iDefault = ETrue;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( &children );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::InitSoftkeyItemL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::InitSoftkeyItemImageL( CXnSoftkeyItem& aItem)
+ {
+ CXnNodePluginIf* node( aItem.iNode );
+
+ // No layout calulations needed
+ node->SetLayoutCapable( EFalse );
+
+ if ( aItem.iPosition == CEikButtonGroupContainer::EMiddleSoftkeyPosition )
+ {
+ aItem.iImageOn = ETrue;
+ return;
+ }
+
+ CXnProperty* pathProp( node->PathL() );
+ if( pathProp )
+ {
+ HBufC* bitmapPath( NULL );
+ HBufC* maskPath( NULL );
+
+ bitmapPath = pathProp->StringValueL();
+ CleanupStack::PushL( bitmapPath );
+ TInt count( 1 );
+
+ CXnProperty* maskProp( node->MaskPathL() );
+
+ if( maskProp )
+ {
+ maskPath = maskProp->StringValueL();
+ CleanupStack::PushL( maskPath );
+ count++;
+ }
+
+ CFbsBitmap* bitmap( NULL );
+ CFbsBitmap* mask( NULL );
+
+ // Call base class to get bitmap and mask
+ GetBitmapAndMask( bitmapPath ? *bitmapPath : KNullDesC(),
+ maskPath ? *maskPath : KNullDesC(),
+ bitmap, mask );
+
+ aItem.iImageOn = ETrue;
+ aItem.iBitmap = bitmap;
+ aItem.iMask = mask;
+
+ CXnProperty* maskInvertedProp( node->GetPropertyL( XnPropertyNames::image::KMaskInverted ) );
+
+ if( maskInvertedProp )
+ {
+ if( maskInvertedProp->StringValue() == XnPropertyNames::KTrue )
+ {
+ aItem.iInvertMask = ETrue;
+ }
+ }
+
+ CXnProperty* aspectRatioProp( node->GetPropertyL( XnPropertyNames::image::KS60AspectRatio ) );
+
+ if( aspectRatioProp )
+ {
+ if( aspectRatioProp->StringValue() == XnPropertyNames::image::KPreserve )
+ {
+ aItem.iPreserveAspectRatio = ETrue;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( count ); // path and/or mask
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::IsMskAvailable
+//
+// -----------------------------------------------------------------------------
+//
+TBool CXnMenuAdapter::IsMskAvailable()
+ {
+ if( AknLayoutUtils::MSKEnabled() && Layout_Meta_Data::IsMSKEnabled() )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::AddMenuItemL
+//
+// -----------------------------------------------------------------------------
+//
+TInt CXnMenuAdapter::AddMenuItemL( TInt aParentIndex,
+ CXnNodePluginIf* aNode, RPointerArray< const TDesC8 >& aGroups )
+ {
+ if ( !aNode )
+ {
+ return 0;
+ }
+
+ const TDesC8& name( aNode->Type()->Type() );
+
+ TInt retval( 0 );
+
+ TBool showByGroup( EFalse );
+
+ const TDesC8* id( NULL );
+
+ CXnProperty* prop( aNode->IdL() );
+
+ if( prop )
+ {
+ id = &prop->StringValue();
+ }
+ else
+ {
+ // If menuitem doesn't have id, group doesn't affect to it
+ showByGroup = ETrue;
+ }
+
+ if( name == KXnMenuItem ||
+ name == KXnDynMenuItem ||
+ name == KXnWidgetMenuItem )
+ {
+ const TDesC8& ns( aNode->Namespace() );
+
+ for( TInt i = 0; !showByGroup && i < aGroups.Count(); i++ )
+ {
+ const TDesC8& groupId( *(aGroups)[i] );
+
+ CXnNodePluginIf* group( iUiEngine->FindNodeByIdL( groupId, ns ) );
+
+ if( group )
+ {
+ RPointerArray< CXnNodePluginIf >
+ children( group->ChildrenL() );
+
+ CleanupClosePushL( children );
+
+ for( TInt j = 0; j < children.Count(); j++ )
+ {
+ CXnProperty* prop( children[j]->GetPropertyL(
+ XnPropertyNames::action::KName ) );
+
+ if( prop )
+ {
+ const TDesC8& name( prop->StringValue() );
+
+ if( name == *id )
+ {
+ // The menuitem belongs to defined group
+ showByGroup = ETrue;
+ break;
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &children );
+ }
+ }
+
+ if( !showByGroup || !IsNodeVisibleL( *aNode ) )
+ {
+ // Menuitem is invisible
+ return retval;
+ }
+ }
+
+ TXnMenuItem item;
+
+ item.iAutomaticSP = ETrue;
+
+ item.iParentIndex = aParentIndex;
+ item.iData.iFlags = 0;
+
+ CXnNodePluginIf* menuItem( NULL );
+
+ if( name == KXnMenuItem || name == KXnDynMenuItem )
+ {
+ menuItem = aNode;
+ }
+ else if( name == KXnWidgetMenuItem )
+ {
+ TRAP_IGNORE( menuItem = FindWidgetMenuItemL( aNode ) );
+ }
+
+ if( menuItem )
+ {
+ const TDesC8& type( menuItem->Type()->Type() );
+
+ // check first if label comes from view
+ CXnProperty* label( aNode->LabelL() );
+
+ if ( !label )
+ {
+ // get label from widget
+ label = menuItem->LabelL();
+ }
+
+ if( label )
+ {
+ HBufC* itemLabel = label->StringValueL();
+ item.iData.iText.Copy( *itemLabel );
+ delete itemLabel;
+ }
+ else
+ {
+ item.iData.iText.Copy( KNullDesC );
+ }
+
+ TBool okToAdd( ETrue );
+
+ if( type == KXnDynMenuItem )
+ {
+ okToAdd = EFalse;
+
+ if( iObserver )
+ {
+ okToAdd = iObserver->DynInitMenuItemL( menuItem->AppIfL() );
+ }
+ }
+
+ if( okToAdd )
+ {
+ if ( id && *id == KHsShowHelp )
+ {
+ // Help command id must be EAknCmdHelp to get editing input options
+ // shown correctly
+ item.iData.iCommandId = EAknCmdHelp;
+ }
+ else
+ {
+ item.iData.iCommandId = iIdCounter++;
+ }
+
+ item.iData.iCascadeId = 0;
+ item.iNode = menuItem;
+ item.iIsCascade = EFalse;
+ iMenuItems.AppendL( item );
+
+ retval = 1;
+ }
+ }
+
+ if( name == KXnMenu )
+ {
+ // main level menu or submenu (cascade)
+ item.iData.iCommandId = iIdCounter++;
+
+ if( aParentIndex == -1 )
+ {
+ item.iData.iCascadeId = R_AVKON_MENUPANE_EMPTY;
+ }
+ else
+ {
+ item.iData.iCascadeId = iIdCounter++;
+ }
+
+ item.iNode = aNode;
+ item.iIsCascade = ETrue;
+ iMenuItems.AppendL( item );
+
+ TInt currentIndex( iMenuItems.Count() - 1 );
+
+ RPointerArray< CXnNodePluginIf > children( aNode->ChildrenL() );
+ CleanupClosePushL( children );
+
+ TInt count( 0 );
+
+ for( TInt i = 0; i < children.Count(); i++ )
+ {
+ count += AddMenuItemL( currentIndex, children[i], aGroups );
+ }
+
+ if( aParentIndex != -1 && count == 0 )
+ {
+ // Empty submenu, don't show it
+ iMenuItems.Delete( currentIndex );
+ // Reverse counter as well
+ iIdCounter -= 2;
+ }
+
+ CleanupStack::PopAndDestroy( &children );
+
+ retval = count;
+ }
+
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::PopulateMenuL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::PopulateMenuL()
+ {
+ iMenuItems.Reset();
+
+ iIdCounter = KMenuCommandFirst;
+
+ RPointerArray< const TDesC8 > groups;
+ CleanupClosePushL( groups );
+
+ if ( !iUiEngine->IsTextEditorActive() )
+ {
+ if( iUiEngine->EditMode() )
+ {
+ groups.AppendL(
+ iContextMenu ? &KContextEditMode : &KEditMode );
+ }
+ else
+ {
+ groups.AppendL(
+ iContextMenu ? &KContextNormalMode : &KNormalMode );
+ }
+ }
+
+ if ( !iContextMenu )
+ {
+ groups.AppendL( &KAlwaysShown );
+ }
+
+ // Recursively add menuitems
+ AddMenuItemL( -1, iMenuBarNode, groups );
+
+ CleanupStack::PopAndDestroy( &groups );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::OfferKeyEventL
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CXnMenuAdapter::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+ {
+ TKeyResponse resp( EKeyWasNotConsumed );
+
+ if( IsMenuFocused() && aKeyEvent.iScanCode == EStdKeyNo )
+ {
+ StopDisplayingMenu();
+
+ iKeyEventNode = NULL;
+
+ return resp;
+ }
+
+ TInt pos( KErrNotFound );
+
+ if( aKeyEvent.iScanCode == EStdKeyDevice0 )
+ {
+ pos = CEikButtonGroupContainer::ELeftSoftkeyPosition;
+ }
+ else if( aKeyEvent.iScanCode == EStdKeyDevice1 )
+ {
+ pos = CEikButtonGroupContainer::ERightSoftkeyPosition;
+ }
+ else if( aKeyEvent.iScanCode == EStdKeyDevice3 )
+ {
+ pos = CEikButtonGroupContainer::EMiddleSoftkeyPosition;
+ }
+
+ CXnSoftkeyItem* softkey( NULL );
+
+ if ( pos != KErrNotFound )
+ {
+ softkey = SoftkeyItemL( pos );
+ }
+
+ if ( softkey )
+ {
+ CXnNodePluginIf* node( softkey->iNode );
+
+ if( aType == EEventKeyDown )
+ {
+ iKeyEventNode = node;
+ }
+
+ if( node && node == iKeyEventNode )
+ {
+ // Let base class handle the event
+ resp = CXnControlAdapter::OfferKeyEventL( aKeyEvent, aType );
+ }
+ }
+
+ if( aType == EEventKeyUp )
+ {
+ iKeyEventNode = NULL;
+ }
+
+ return resp;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::HandlePointerEventL
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ CXnNodePluginIf* node( FindSoftkeyItemByPosition( aPointerEvent.iParentPosition ) );
+
+ if( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ // The sofkey node which received the button down event
+ iPointerEventNode = node;
+ }
+
+ if( node && node == iPointerEventNode )
+ {
+ iUiEngine->DisableRenderUiLC();
+
+ // Handle event if location is in the grabbing node's area
+ CXnControlAdapter::HandlePointerEventL( aPointerEvent );
+
+ CleanupStack::PopAndDestroy();
+ }
+
+ if( aPointerEvent.iType == TPointerEvent::EButton1Up )
+ {
+ // Reset grabbing node after the up event
+ iPointerEventNode = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::DoEnterPowerSaveModeL
+// Enter power save mode
+// -----------------------------------------------------------------------------
+void CXnMenuAdapter::DoEnterPowerSaveModeL(TModeEvent /*aEvent*/)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::DoExitPowerSaveModeL
+// Enter power save mode
+// -----------------------------------------------------------------------------
+void CXnMenuAdapter::DoExitPowerSaveModeL(TModeEvent /*aEvent*/)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::RestoreMenuL
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::RestoreMenuL( CCoeControl* aMenuControl, TInt aResourceId,
+ TMenuType aType )
+ {
+ // let all menu pane resources propogate to default implementation,
+ // otherwise panic when trying to display menu
+ if ( aType == MEikMenuObserver::EMenuPane )
+ {
+ if ( !( KMenuCommandFirst <= aResourceId &&
+ aResourceId <= KMenuCommandLast )
+ && aResourceId != R_AVKON_MENUPANE_EMPTY )
+ {
+ MEikMenuObserver::RestoreMenuL( aMenuControl,aResourceId, aType );
+ }
+ else
+ {
+ AddItemsToMenuPaneL( ( CEikMenuPane* )aMenuControl, aResourceId );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::DynInitMenuPaneL
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::DynInitMenuPaneL( TInt aResourceId,
+ CEikMenuPane* aMenuPane )
+ {
+ if ( aResourceId == R_AVKON_MENUPANE_EMPTY )
+ {
+ RestoreMenuL( aMenuPane, aResourceId, MEikMenuObserver::EMenuPane );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetEmphasis
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetEmphasis( CCoeControl* aMenuControl,
+ TBool aEmphasis )
+ {
+ if ( iMenuBar && aMenuControl == iMenuBar )
+ {
+ CXnAppUiAdapter* appui(
+ static_cast< CXnAppUiAdapter* >( iAvkonAppUi ) );
+
+ if ( aEmphasis && !iMenuShown )
+ {
+ iMenuShown = ETrue;
+
+ TRAP_IGNORE( appui->AddToStackL( appui->View(),
+ iMenuBar,
+ ECoeStackPriorityMenu ) );
+
+ iMenuBar->MakeVisible( ETrue );
+ }
+ else if ( !aEmphasis && iMenuShown )
+ {
+ iMenuShown = EFalse;
+
+ appui->RemoveFromStack( iMenuBar );
+
+ iMenuBar->MakeVisible( EFalse );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::ProcessCommandL
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::ProcessCommandL( TInt aCommand )
+ {
+ if ( ( KMenuCommandFirst <= aCommand && aCommand <= KMenuCommandLast ) ||
+ aCommand == EAknCmdHelp )
+ {
+ // find item for this command
+ for ( TInt i = 0; i< iMenuItems.Count(); i++ )
+ {
+ if ( iMenuItems[i].iData.iCommandId == aCommand )
+ {
+ CXnNodePluginIf* node( iMenuItems[i].iNode );
+
+ if ( node )
+ {
+ StopDisplayingMenu();
+
+ iUiEngine->DisableRenderUiLC();
+
+ node->SetStateL( XnPropertyNames::style::common::KActive );
+
+ CleanupStack::PopAndDestroy();
+
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ StopDisplayingMenu();
+
+ if( aCommand == EEikCmdEditPaste )
+ {
+ // Paste event for AknCcpuSupport
+ TKeyEvent pasteEvent =
+ { EKeyF18, EEikCmdEditPaste, EModifierCtrl, 1 };
+
+ iCoeEnv->SimulateKeyEventL( pasteEvent, EEventKey );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetContainerL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetContainerL( CEikButtonGroupContainer& aContainer )
+ {
+ User::LeaveIfNull( &aContainer );
+
+ TBool updateNeeded( EFalse );
+
+ TInt statusPaneId( iAvkonAppUi->StatusPane()->CurrentLayoutResId() );
+
+ if(iPreviousMenuPaneId != statusPaneId)
+ {
+ updateNeeded = ETrue;
+ iPreviousMenuPaneId = statusPaneId;
+ }
+
+ if((&aContainer) && (iContainer != &aContainer || updateNeeded))
+ {
+ iUpdateLskAppearance = ETrue;
+ iUpdateMskAppearance = ETrue;
+ iUpdateRskAppearance = ETrue;
+ }
+
+ iContainer = &aContainer;
+
+ CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) );
+ cba->SetButtonGroupFlags( cba->ButtonGroupFlags() | EEikCbaFlagSemiTransparent );
+
+ UpdateSoftkeyAppearancesL();
+ }
+
+//--------------------------------------------------------------
+// CXnMenuAdapter::IsMenuFocused
+// ------------------------------------------------------------
+TBool CXnMenuAdapter::IsMenuFocused()
+ {
+ return iMenuShown;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::TryDisplayingMenuL
+// Displays options menu
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::TryDisplayingMenuL( const TDesC& aMenuNodeId,
+ TBool aContextMenu )
+ {
+ HBufC8* id = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aMenuNodeId );
+ CleanupStack::PushL( id );
+ CXnNodePluginIf* node( iUiEngine->FindNodeByIdL( *id, iRootNode->Namespace() ) );
+ CleanupStack::PopAndDestroy( id );
+
+ iContextMenu = aContextMenu;
+
+ if( node && node->Type()->Type() == KXnMenu )
+ {
+ TryDisplayingMenuL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::TryDisplayingMenuL
+// Displays options menu if it is defined for the softkey item
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::TryDisplayingMenuL()
+ {
+ StopDisplayingMenu();
+
+ CreateMenuBarL();
+
+ if ( iMenuBar )
+ {
+ CEikMenuBarTitle* title = new( ELeave ) CEikMenuBarTitle;
+ CleanupStack::PushL( title );
+
+ title->iData.iMenuPaneResourceId = R_AVKON_MENUPANE_EMPTY;
+ title->iTitleFlags = 0;
+
+ // this cannot be done earlyer, than this callback
+ iMenuBar->TitleArray()->AddTitleL( title );
+ CleanupStack::Pop( title );
+
+ iMenuBar->TryDisplayMenuBarL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::StopDisplayingMenu
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::StopDisplayingMenu()
+ {
+ if( iMenuBar )
+ {
+ iMenuBar->StopDisplayingMenuBar();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::CreateMenuBarL
+// ---------------------------------------------------------------------------
+//
+void CXnMenuAdapter::CreateMenuBarL()
+ {
+ if ( iMenuBar )
+ {
+ // All ready created
+ return;
+ }
+
+ // Create
+ RPointerArray< CXnNodePluginIf > children( iRootNode->ChildrenL() );
+ CleanupClosePushL( children );
+
+ for( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNodePluginIf* node( children[i] );
+
+ TPtrC8 type( node->Type()->Type() );
+
+ // Currently only one menubar is allowed,
+ // but it can be assigned to any of the CBAs
+ // To change this, we have to create and maintain a list of menubars
+ if( type == KXnMenu )
+ {
+ iMenuBarNode = node;
+
+ iMenuBar = new ( ELeave ) CEikMenuBar;
+ iMenuBar->ConstructL( this );
+ iMenuBar->SetMenuType( MenuTypeL( *iRootNode ) );
+
+ // All done
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( &children );
+ }
+
+//--------------------------------------------------------------
+// CXnMenuAdapter::HandleResourceChange
+// Handles a change to the control's resources of type aType
+// ------------------------------------------------------------
+void CXnMenuAdapter::HandleResourceChange( TInt aType )
+ {
+ if( iMenuBar )
+ {
+ iMenuBar->HandleResourceChange( aType );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetSoftKeyImageL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetSoftKeyImageL(
+ CFbsBitmap* aBitmap,
+ CFbsBitmap* aMask,
+ XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos,
+ CXnNodeAppIf* aNode,
+ TBool aPreserveAspectRatio, TBool aInvertMask,
+ TBool aTransferOwnership)
+ {
+ if( ( !aBitmap && !aMask ) || aPos == XnMenuInterface::MXnMenuInterface::ECenter )
+ {
+ // No images present and image can be set only to lsk or rsk
+ User::Leave( KErrArgument );
+ }
+
+ CXnSoftkeyItem* softkey(NULL);
+
+ if( aPos == XnMenuInterface::MXnMenuInterface::ELeft)
+ {
+ if( aNode )
+ {
+ softkey = SoftkeyItemL( aNode );
+ }
+ else
+ {
+ softkey = SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition);
+ }
+ iUpdateLskAppearance = ETrue;
+ }
+ else if(aPos == XnMenuInterface::MXnMenuInterface::ERight)
+ {
+ if( aNode )
+ {
+ softkey = SoftkeyItemL( aNode );
+ }
+ else
+ {
+ softkey = SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition);
+ }
+ iUpdateRskAppearance = ETrue;
+ }
+
+ if(softkey)
+ {
+ softkey->Reset();
+ softkey->iImageOn = ETrue;
+
+ // Save new icon data
+ softkey->iBitmap = aBitmap;
+ softkey->iMask = aMask;
+ softkey->iPreserveAspectRatio = aPreserveAspectRatio;
+ softkey->iInvertMask = aInvertMask;
+ softkey->iOwnBitmaps = aTransferOwnership;
+ // Image set, mark node as dirty
+ softkey->iNode->SetDirtyL();
+
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetSoftKeyImageL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetSoftKeyImageL( const TAknsItemID& aId,
+ const TDesC& aBmpFile,
+ const TInt32 aBmp,
+ const TInt32 aBmpM,
+ XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos,
+ TBool /*aEnable*/ )
+ {
+ CXnSoftkeyItem* softkey( NULL );
+
+ switch( aPos )
+ {
+ case XnMenuInterface::MXnMenuInterface::ECenter:
+ {
+ softkey = SoftkeyItemL( CEikButtonGroupContainer::EMiddleSoftkeyPosition );
+ iUpdateMskAppearance = ETrue;
+ break;
+ }
+ // Currently only MSK icon updating supported here
+ case XnMenuInterface::MXnMenuInterface::ELeft:
+ case XnMenuInterface::MXnMenuInterface::ERight:
+ default:
+ {
+ break;
+ }
+ }
+
+ if( softkey )
+ {
+ softkey->Reset();
+ softkey->iImageOn = ETrue;
+
+ // Save new icon data
+ softkey->iBitmap = NULL;
+ softkey->iMask = NULL;
+ softkey->iPreserveAspectRatio = EFalse;
+ softkey->iInvertMask = EFalse;
+ softkey->iOwnBitmaps = ETrue;
+ delete softkey->iBmpFile;
+ softkey->iBmpFile = NULL;
+ softkey->iBmpFile = aBmpFile.AllocL();
+ softkey->iId.Set( aId );
+ softkey->iBmp = aBmp;
+ softkey->iBmpM = aBmpM;
+
+ // Image set, mark node as dirty
+ softkey->iNode->SetDirtyL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetSoftKeyTextL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetSoftKeyTextL( const TDesC& aText,
+ XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos )
+ {
+ CXnSoftkeyItem* softkey(NULL);
+
+ switch( aPos )
+ {
+ case XnMenuInterface::MXnMenuInterface::ELeft:
+ softkey = SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition);
+ iUpdateLskAppearance = ETrue;
+ break;
+ case XnMenuInterface::MXnMenuInterface::ERight:
+ softkey = SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition);
+ iUpdateRskAppearance = ETrue;
+ break;
+ case XnMenuInterface::MXnMenuInterface::ECenter:
+ softkey = SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition);
+ iUpdateMskAppearance = ETrue;
+ break;
+ default:
+ break;
+ }
+ if(softkey)
+ {
+ softkey->Reset();
+
+ softkey->iImageOn = EFalse;
+
+ softkey->iLabel = aText.AllocL();
+ // Text set, mark parent as dirty
+ softkey->iNode->SetDirtyL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetSoftKeyL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetSoftKeyL( CXnNodePluginIf* aSoftkeyNode,
+ XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos )
+ {
+
+ CXnSoftkeyItem* item = AppendSoftkeyItemL(aSoftkeyNode);
+ switch(aPos)
+ {
+ case XnMenuInterface::MXnMenuInterface::ELeft:
+ if(item)
+ {
+ iVisibleLSK = item;
+ }
+ else
+ {
+ iVisibleLSK = NULL;
+ }
+ iUpdateLskAppearance = ETrue;
+ break;
+ case XnMenuInterface::MXnMenuInterface::ECenter:
+ if(item)
+ {
+ iVisibleMSK = item;
+ }
+ else
+ {
+ iVisibleMSK = NULL;
+ }
+ iUpdateMskAppearance = ETrue;
+ break;
+ case XnMenuInterface::MXnMenuInterface::ERight:
+ if(item)
+ {
+ iVisibleRSK = item;
+ }
+ else
+ {
+ iVisibleRSK = NULL;
+ }
+ iUpdateRskAppearance = ETrue;
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SoftKeyL
+//
+// -----------------------------------------------------------------------------
+//
+CXnNodePluginIf* CXnMenuAdapter::SoftKeyL( XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos )
+ {
+ CXnNodePluginIf* node(NULL);
+ CXnSoftkeyItem* item = SoftkeyItemL(aPos);
+ if(item)
+ {
+ node = item->iNode;
+ }
+ return node;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::KeyEventNode
+//
+// -----------------------------------------------------------------------------
+//
+CXnNodePluginIf* CXnMenuAdapter::KeyEventNode()
+ {
+ return iKeyEventNode;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::HandleScreenDeviceChangedL
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::HandleScreenDeviceChangedL()
+ {
+ CXnSoftkeyItem* left =
+ SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition);
+
+ CXnSoftkeyItem* middle =
+ SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition);
+ CXnSoftkeyItem* right =
+ SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition);
+
+ if(left && left->iImageOn)
+ {
+ iUpdateLskAppearance = ETrue;
+ left->iNode->SetDirtyL();
+ }
+ if(right && right->iImageOn)
+ {
+ iUpdateRskAppearance = ETrue;
+ right->iNode->SetDirtyL();
+ }
+ if(middle && middle->iImageOn)
+ {
+ iUpdateMskAppearance = ETrue;
+ middle->iNode->SetDirtyL();
+ }
+ CXnControlAdapter::HandleScreenDeviceChangedL();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::HandleMenuPropertyChangeL
+// Change softkey appearance
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::HandleMenuPropertyChangeL(CXnNodePluginIf* aNode, CXnProperty* aProperty)
+ {
+ if ( !aNode || !aProperty )
+ {
+ return;
+ }
+
+ const TDesC8& type( aNode->Type()->Type() );
+
+ if ( type != softkey::KNodeName)
+ {
+ return;
+ }
+
+ // Find target softkey
+ CXnSoftkeyItem* softkey( SoftkeyItemL( aNode ) );
+
+ if ( !softkey )
+ {
+ return;
+ }
+
+ SetUpdateAppearanceL( softkey );
+
+ const TDesC8* name( &KNullDesC8() );
+
+ if ( aProperty )
+ {
+ name = &aProperty->Property()->Name();
+ }
+
+ if ( *name == menu::KLabel )
+ {
+ softkey->Reset();
+ softkey->iImageOn = EFalse;
+ softkey->iLabel = aProperty->StringValueL();
+ }
+ else if ( *name == style::common::KDisplay )
+ {
+ if ( aProperty->StringValue() == XnPropertyNames::style::common::display::KNone )
+ {
+ if ( softkey->iPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition )
+ {
+ EikSoftkeyImage::SetLabel( iContainer,ETrue );
+ iContainer->SetCommandL( CEikButtonGroupContainer::ELeftSoftkeyPosition,KCBACommandFirst, KNullDesC );
+ }
+ else if ( softkey->iPosition == CEikButtonGroupContainer::ERightSoftkeyPosition )
+ {
+ EikSoftkeyImage::SetLabel( iContainer,EFalse );
+ iContainer->SetCommandL( CEikButtonGroupContainer::ERightSoftkeyPosition,KCBACommandSecond, KNullDesC );
+ }
+ else if ( softkey->iPosition == CEikButtonGroupContainer::EMiddleSoftkeyPosition )
+ {
+ iContainer->SetCommandL( CEikButtonGroupContainer::EMiddleSoftkeyPosition,KCBACommandMiddle, KNullDesC );
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::SetObserver
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::SetObserver( XnMenuInterface::MXnMenuObserver& aObserver )
+ {
+ iObserver = &aObserver;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::RemoveObserver
+//
+// -----------------------------------------------------------------------------
+//
+void CXnMenuAdapter::RemoveObserver()
+ {
+ iObserver = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::FindSoftKeyNodeByPosition
+// ---------------------------------------------------------------------------
+//
+TBool CXnMenuAdapter::FindSoftKeyNodeByPosition(
+ const TPoint& aPosition,
+ CXnNodePluginIf*& aNode )
+ {
+ CXnNodePluginIf* ret = FindSoftkeyItemByPosition(aPosition);
+ aNode = ret;
+ return (ret?ETrue:EFalse);
+ }
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::ButtonTouchableRectByPosition
+// Gets a CBA button rectangle. Touchable are is larger than controls rect
+// ---------------------------------------------------------------------------
+//
+TRect CXnMenuAdapter::ButtonTouchableRectByPosition( TInt aPosition)
+ {
+ TRect rect( 0, 0, 0, 0 );
+
+ TRect button1Rect( 0, 0, 0, 0 );
+ TRect button2Rect( 0, 0, 0, 0 );
+ TRect buttonMSKRect( 0, 0, 0, 0 );
+
+ // In touch layouts the button areas are read from the
+ // layout data because they are larger than the actual
+ // control size.
+#ifndef _AVKON_CBA_LSC
+ CCoeControl* container = iContainer->ButtonGroup()->AsControl();
+ TRect containerRect(container->PositionRelativeToScreen(),container->Size());
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::control_pane_g6( 0 ).LayoutLine() );
+ button1Rect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::control_pane_g8( 0 ).LayoutLine() );
+ button2Rect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::control_pane_g7( 0 ).LayoutLine() );
+ buttonMSKRect = layoutRect.Rect();
+#else
+ if ( Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ button1Rect = SoftkeyRectTopTouch();
+ button2Rect= SoftkeyRectBottomTouch();
+
+ }
+ else // portrait
+ {
+ button1Rect = SoftkeyRectLeftTouch();
+ button2Rect = SoftkeyRectRightTouch();
+ }
+#endif
+
+ switch ( aPosition )
+ {
+ case CEikButtonGroupContainer::ELeftSoftkeyPosition:
+ {
+ rect = button1Rect;
+ break;
+ }
+
+ case CEikButtonGroupContainer::ERightSoftkeyPosition:
+ {
+ rect = button2Rect;
+ break;
+ }
+
+ case CEikButtonGroupContainer::EMiddleSoftkeyPosition:
+ {
+ rect = buttonMSKRect;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+
+ return rect;
+ }
+
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::FindSoftkeyNodeL
+// ---------------------------------------------------------------------------
+//
+CXnNodePluginIf* CXnMenuAdapter::FindSoftkeyNodeL(const TDesC8& aNodeType)
+ {
+ CXnNodePluginIf* ret(0);
+
+ RPointerArray< CXnNodePluginIf > children( iRootNode->ChildrenL() );
+ CleanupClosePushL( children );
+ for(TInt i=0;i<children.Count();++i)
+ {
+ if(children[i]->Type()->Type() == XnPropertyNames::softkey::KNodeName)
+ {
+ if( SoftkeyPlaceL(*children[i]) == aNodeType
+ && IsNodeVisibleL( *children[i]) )
+ {
+ ret = children[i];
+ break;
+ }
+
+ }
+ }
+ CleanupStack::PopAndDestroy( &children );
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::UpdateSoftkeyAppearancesL
+// ---------------------------------------------------------------------------
+//
+void CXnMenuAdapter::UpdateSoftkeyAppearancesL()
+ {
+
+ if(iUpdateLskAppearance)
+ {
+ CXnSoftkeyItem* left =
+ SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition);
+ if( left )
+ {
+ SetSoftkeyAppearanceL(*left);
+ }
+ iUpdateLskAppearance = EFalse;
+ }
+ if(iUpdateRskAppearance)
+ {
+ CXnSoftkeyItem* right =
+ SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition);
+ if(right)
+ {
+ SetSoftkeyAppearanceL(*right);
+ }
+ iUpdateRskAppearance = EFalse;
+ }
+ if(iUpdateMskAppearance)
+ {
+ CXnSoftkeyItem* middle =
+ SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition);
+ if(middle)
+ {
+ SetSoftkeyAppearanceL(*middle);
+ }
+ iUpdateMskAppearance = EFalse;
+ }
+ }
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::ChangeSoftkeyImageL
+// ---------------------------------------------------------------------------
+//
+void CXnMenuAdapter::ChangeSoftkeyImageL(const CXnSoftkeyItem& aSoftkey)
+ {
+ if ( aSoftkey.iPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition ||
+ aSoftkey.iPosition == CEikButtonGroupContainer::ERightSoftkeyPosition )
+ {
+ TSize size;
+ if(AknLayoutUtils::PenEnabled())
+ {
+ size = SoftkeyImageRect(*iContainer,aSoftkey.iPosition).Size();
+ }
+ else
+ {
+ size = SoftkeyRectL( *iContainer,aSoftkey.iPosition, aSoftkey.iImageOn ).Size();
+ }
+
+ CEikImage* image( PrepareSoftkeyImageL( aSoftkey, size ) );
+ TBool left(ETrue);
+
+ if(aSoftkey.iPosition != CEikButtonGroupContainer::ELeftSoftkeyPosition)
+ {
+ left = EFalse;
+ }
+ EikSoftkeyImage::SetImage( iContainer, *image, left );
+ }
+ else if ( aSoftkey.iBmpFile )
+ {
+ CEikCba* cba = static_cast< CEikCba* >( iContainer->ButtonGroup() );
+ // use iAvkonAppUi
+ CAknAppUi* appUi = static_cast<CAknAppUi*>( CEikonEnv::Static()->AppUi() );
+ cba->UpdateMSKIconL(
+ aSoftkey.iId,
+ aSoftkey.iBmpFile->Des(),
+ aSoftkey.iBmp,
+ aSoftkey.iBmpM,
+ ETrue );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::AddItemsToMenuPaneL
+// ---------------------------------------------------------------------------
+//
+void CXnMenuAdapter::AddItemsToMenuPaneL(CEikMenuPane* aMenuPane, TInt aResourceId)
+ {
+ TInt parentIndexForNotification( 0 );
+
+ for ( TInt i = 0; i< iMenuItems.Count(); i++ )
+ {
+ // find items belong to this pane
+ TInt parent( iMenuItems[i].iParentIndex );
+
+ if ( parent >= 0 )
+ {
+ TInt cid( iMenuItems[parent].iData.iCascadeId );
+
+ if ( cid == aResourceId )
+ {
+ if ( parent > 0 )
+ {
+ parentIndexForNotification = parent;
+ break;
+ }
+ }
+ }
+ }
+
+ TBool selectionEnabled( EFalse );
+ TBool isRadio( EFalse );
+
+ if ( parentIndexForNotification != 0 )
+ {
+ CXnNodePluginIf* node( iMenuItems[parentIndexForNotification].iNode );
+
+ CXnProperty* property( node->GetPropertyL( _L8( "selectiontype" ) ) );
+
+ if ( property && property->StringValue() == _L8( "multi" ) )
+ {
+ selectionEnabled = ETrue;
+ }
+ else if ( property && property->StringValue() == _L8( "single" ) )
+ {
+ selectionEnabled = ETrue;
+ isRadio = ETrue;
+ }
+
+ node->SetStateL( XnPropertyNames::style::common::KActive );
+ node->UnsetStateL( XnPropertyNames::style::common::KActive );
+ }
+
+ PopulateMenuL();
+
+ for ( TInt i = 0; i< iMenuItems.Count(); i++ )
+ {
+ // find items belong to this pane
+ TInt parent( iMenuItems[i].iParentIndex );
+
+ if ( parent >= 0 )
+ {
+ TInt cid( iMenuItems[parent].iData.iCascadeId );
+
+ if ( cid == aResourceId )
+ {
+ if ( selectionEnabled )
+ {
+ if ( !isRadio )
+ {
+ iMenuItems[i].iData.iFlags |=
+ EEikMenuItemCheckBox;
+ }
+ else
+ {
+ iMenuItems[i].iData.iFlags |=
+ EEikMenuItemRadioStart|
+ EEikMenuItemRadioMiddle|
+ EEikMenuItemRadioEnd;
+ }
+ }
+
+ aMenuPane->AddMenuItemL( iMenuItems[i].iData );
+
+ if ( selectionEnabled )
+ {
+ CXnProperty* property(
+ iMenuItems[i].iNode->GetPropertyL( XnPropertyNames::menu::KChecked ) );
+
+ if ( property && property->StringValue() == XnPropertyNames::KTrue )
+ {
+ aMenuPane->SetItemButtonState(
+ iMenuItems[i].iData.iCommandId, EEikMenuItemSymbolOn );
+ }
+ }
+ }
+ }
+ } // for end
+ }
+
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::AppendSoftkeyItemL
+// ---------------------------------------------------------------------------
+//
+CXnSoftkeyItem* CXnMenuAdapter::AppendSoftkeyItemL(CXnNodePluginIf* aNode)
+ {
+ if(!aNode)
+ {
+ return NULL;
+ }
+ CXnProperty* property =
+ aNode->GetPropertyL( XnPropertyNames::softkey::KTypeAttribute );
+ if(!property)
+ {
+ return NULL;
+ }
+ const TDesC8& skType = property->StringValue();
+ if( skType != XnPropertyNames::softkey::type::KRight &&
+ skType != XnPropertyNames::softkey::type::KLeft &&
+ skType != XnPropertyNames::softkey::type::KMiddle )
+ {
+ return NULL;
+ }
+ for( TInt i=0; i<iSoftkeyItems.Count(); i++ )
+ {
+ if( iSoftkeyItems[i]->iNode == aNode )
+ {
+ return iSoftkeyItems[i];
+ }
+ }
+ CXnSoftkeyItem* softkey(0);
+ softkey = new (ELeave) CXnSoftkeyItem;
+ CleanupStack::PushL(softkey);
+
+ if ( skType == XnPropertyNames::softkey::type::KRight )
+ {
+ softkey->iPosition = CEikButtonGroupContainer::ERightSoftkeyPosition;
+ softkey->iCommandId = KCBACommandSecond;
+ }
+ else if ( skType == XnPropertyNames::softkey::type::KLeft )
+ {
+ softkey->iPosition = CEikButtonGroupContainer::ELeftSoftkeyPosition;
+ softkey->iCommandId = KCBACommandFirst;
+ }
+ else
+ {
+ softkey->iPosition = CEikButtonGroupContainer::EMiddleSoftkeyPosition;
+ softkey->iCommandId = KCBACommandMiddle;
+ }
+
+ softkey->iNode = aNode;
+
+ CXnProperty* labelProp( aNode->LabelL() );
+ CXnProperty* targetProp( aNode->GetPropertyL(KXnTarget) );
+
+ if(labelProp)
+ {
+ softkey->iImageOn = EFalse;
+ softkey->iLabel = labelProp->StringValueL();
+ }
+ else if(targetProp)
+ {
+ softkey->iImageOn = EFalse;
+ softkey->iLabel = FindSoftkeyLabelL(aNode);
+ }
+ else
+ {
+ InitSoftkeyItemImageL( *softkey );
+ }
+
+ softkey->iUpdateAppearance = ETrue;
+ iSoftkeyItems.AppendL(softkey);
+ CleanupStack::Pop(softkey);
+ return softkey;
+ }
+// ---------------------------------------------------------------------------
+// CXnMenuAdapter::SoftkeyPlaceL
+// ---------------------------------------------------------------------------
+//
+const TDesC8& CXnMenuAdapter::SoftkeyPlaceL(CXnNodePluginIf& aNode)
+ {
+ CXnProperty* property =
+ aNode.GetPropertyL( XnPropertyNames::softkey::KTypeAttribute );
+
+ if( property)
+ {
+ return property->StringValue();
+ }
+ return KNullDesC8;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::FindSoftkeyItemByPosition
+//
+// -----------------------------------------------------------------------------
+CXnNodePluginIf* CXnMenuAdapter::FindSoftkeyItemByPosition( const TPoint& aPosition )
+ {
+ CXnNodePluginIf* softkey(0);
+ TRAP_IGNORE( softkey = DoFindSoftkeyItemByPositionL( aPosition ) );
+ return softkey;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::DoFindSoftkeyItemByPositionL
+//
+// -----------------------------------------------------------------------------
+CXnNodePluginIf* CXnMenuAdapter::DoFindSoftkeyItemByPositionL( const TPoint& aPosition )
+ {
+ TRect lsk( ButtonTouchableRectByPosition(CEikButtonGroupContainer::ELeftSoftkeyPosition) );
+ TRect rsk( ButtonTouchableRectByPosition(CEikButtonGroupContainer::ERightSoftkeyPosition) );
+ TRect msk( ButtonTouchableRectByPosition(CEikButtonGroupContainer::EMiddleSoftkeyPosition) );
+
+ CXnNodePluginIf* softkey(NULL);
+ CXnSoftkeyItem* item(NULL);
+ if ( lsk.Contains(aPosition) )
+ {
+ item = SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition);
+ }
+ else if(msk.Contains(aPosition))
+ {
+ item = SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition);
+ }
+ else if( rsk.Contains(aPosition) )
+ {
+ item = SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition);
+ }
+ if(item)
+ {
+ softkey = item->iNode;
+ }
+ return softkey;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+CXnSoftkeyItem* CXnMenuAdapter::SoftkeyItemL(TInt aPosition)
+ {
+ CXnSoftkeyItem* softkeyItem(0);
+ if(iVisibleLSK && aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition)
+ {
+ return iVisibleLSK;
+ }
+ else if(iVisibleRSK && aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition)
+ {
+ return iVisibleRSK;
+ }
+ else if(iVisibleMSK && aPosition == CEikButtonGroupContainer::EMiddleSoftkeyPosition)
+ {
+ return iVisibleMSK;
+ }
+
+ // return default
+ for(TInt i=0;i<iSoftkeyItems.Count();++i)
+ {
+ softkeyItem = iSoftkeyItems[i];
+ if(softkeyItem->iPosition == aPosition &&
+ softkeyItem->iDefault &&
+ IsNodeVisibleL(*softkeyItem->iNode))
+ {
+ return softkeyItem;
+ }
+ }
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+CXnSoftkeyItem* CXnMenuAdapter::SoftkeyItemL(CXnNodePluginIf* aNode)
+ {
+ CXnSoftkeyItem* softkeyItem(0);
+ for(TInt i=0;i<iSoftkeyItems.Count();++i)
+ {
+ softkeyItem = iSoftkeyItems[i];
+ if(softkeyItem->iNode == aNode)
+ {
+ return softkeyItem;
+ }
+ }
+ return NULL;
+ }
+
+CXnSoftkeyItem* CXnMenuAdapter::SoftkeyItemL(CXnNodeAppIf* aNode)
+ {
+ CXnSoftkeyItem* softkeyItem(0);
+ for(TInt i=0;i<iSoftkeyItems.Count();++i)
+ {
+ softkeyItem = iSoftkeyItems[i];
+ if(&(softkeyItem->iNode->AppIfL()) == aNode)
+ {
+ return softkeyItem;
+ }
+ }
+ return NULL;
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+void CXnMenuAdapter::SetUpdateAppearanceL(CXnSoftkeyItem* aItem)
+ {
+ if ( aItem && IsNodeVisibleL( *aItem->iNode ) )
+ {
+ aItem->iNode->SetDirtyL();
+
+ switch ( aItem->iPosition )
+ {
+ case CEikButtonGroupContainer::ELeftSoftkeyPosition:
+ iUpdateLskAppearance = ETrue;
+ iVisibleLSK = NULL;
+ break;
+ case CEikButtonGroupContainer::EMiddleSoftkeyPosition:
+ iUpdateMskAppearance = ETrue;
+ iVisibleMSK = NULL;
+ break;
+ case CEikButtonGroupContainer::ERightSoftkeyPosition:
+ iUpdateRskAppearance = ETrue;
+ iVisibleRSK = NULL;
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::FindWidgetMenuItemL
+//
+// -----------------------------------------------------------------------------
+CXnNodePluginIf* CXnMenuAdapter::FindWidgetMenuItemL( CXnNodePluginIf* aNode )
+ {
+ CXnNodePluginIf* focusedNode( iUiEngine->FocusedNodeL() );
+
+ CXnNodePluginIf* menuItem( NULL );
+
+ if ( focusedNode && aNode )
+ {
+ // Get <plugin> element
+ CXnNodePluginIf& pluginNode( iUiEngine->PluginNodeL( focusedNode ) );
+
+ CXnNodePluginIf* widget( FindWidgetElementL( pluginNode ) );
+
+ CXnNodePluginIf* widgetExtNode( NULL );
+
+ if( widget )
+ {
+ widgetExtNode = FindChildL( *widget, KXnMenuExtension );
+ }
+
+ if( !widgetExtNode )
+ {
+ widgetExtNode = focusedNode;
+ }
+
+ if ( widgetExtNode )
+ {
+ CXnProperty* prop( aNode->GetPropertyL( KXnSource ) );
+
+ if ( prop )
+ {
+ const TDesC8& source( prop->StringValue() );
+
+ // Try to find <menuitem>
+ menuItem = FindChildL( *widgetExtNode,
+ KXnMenuItem,
+ source );
+
+ if ( !menuItem )
+ {
+ // Try to find <dynmenuitem>
+ menuItem = FindChildL( *widgetExtNode,
+ KXnDynMenuItem,
+ source );
+ }
+ }
+ }
+ }
+
+ if( menuItem && IsNodeVisibleL( *menuItem ) )
+ {
+ return menuItem;
+ }
+
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnMenuAdapter::FindSoftkeyLabelL
+//
+// -----------------------------------------------------------------------------
+HBufC* CXnMenuAdapter::FindSoftkeyLabelL( CXnNodePluginIf* aNode )
+ {
+ if( !aNode )
+ {
+ return NULL;
+ }
+
+ CXnProperty* targerProp( aNode->GetPropertyL( KXnTarget ) );
+
+ if ( targerProp && iRootNode )
+ {
+ CXnNodePluginIf* widgetSoftkeyNode(
+ FindChildL( *iRootNode,
+ KXnWidgetSoftkey,
+ targerProp->StringValue() ) );
+
+ if ( widgetSoftkeyNode )
+ {
+ CXnProperty* label( widgetSoftkeyNode->LabelL() );
+
+ if( label )
+ {
+ return label->StringValueL();
+ }
+ }
+ }
+
+ return NULL;;
+ }
+
+//end of file