diff -r 000000000000 -r f72a12da539e idlehomescreen/xmluirendering/uiengine/src/xnpopupcontroladapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idlehomescreen/xmluirendering/uiengine/src/xnpopupcontroladapter.cpp Thu Dec 17 08:40:49 2009 +0200 @@ -0,0 +1,349 @@ +/* +* Copyright (c) 2008 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: Popup control adapter +* +*/ + +// System includes +#include +#include +#include +#include +#include + +// User includes +#include "xnappuiadapter.h" +#include "xnproperty.h" +#include "xncontroladapter.h" +#include "xnnodepluginif.h" +#include "xnnode.h" +#include "xntype.h" +#include "xnuiengine.h" +#include "xneditor.h" +#include "xnhittest.h" +#include "xnfocuscontrol.h" + +#include "xnpopupcontroladapter.h" + +// Constants +_LIT8( KMenuItem, "menuitem" ); +_LIT8( KDynMenuItem, "dynmenuitem" ); +_LIT8( KWidgetMenuItem, "widgetmenuitem" ); +_LIT8( KMenuExtension, "menuextension" ); + +_LIT8( KSource, "source" ); +_LIT8( KTarget, "target" ); + +// ============================ LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// FindWidgetMenuItemL +// ----------------------------------------------------------------------------- +// +CXnNode* FindWidgetMenuItemL( const TDesC8& aSource, + CXnNode& aPlugin ) + { + if( aPlugin.Children().Count() == 0 ) + { + return NULL; + } + + // Get element from the element + RPointerArray< CXnNode >& children( aPlugin.Children()[0]->Children() ); + + for ( TInt i = children.Count() - 1; i >= 0; i-- ) + { + if ( children[i]->Type()->Type() == KMenuExtension ) + { + RPointerArray< CXnNode >& items( children[i]->Children() ); + + for ( TInt i = 0; i < items.Count(); i++ ) + { + CXnProperty* prop( items[i]->GetPropertyL( KTarget ) ); + + if ( prop && prop->StringValue() == aSource ) + { + return items[i]; + } + } + + break; + } + } + + return NULL; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::NewL +// Two-phased constructor. Can leave. +// ----------------------------------------------------------------------------- +// +CXnPopupControlAdapter* CXnPopupControlAdapter::NewL( CXnNodePluginIf& aNode ) + { + CXnPopupControlAdapter* self = + new ( ELeave ) CXnPopupControlAdapter(); + + CleanupStack::PushL( self ); + + self->ConstructL( aNode ); + + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::~CXnPopupControlAdapter +// Destructor. +// ----------------------------------------------------------------------------- +// +CXnPopupControlAdapter::~CXnPopupControlAdapter() + { + delete iStylusPopupMenu; + + iMenuItems.Reset(); + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::CXnPopupControlAdapter +// C++ default constructor. Must not leave. +// ----------------------------------------------------------------------------- +// +CXnPopupControlAdapter::CXnPopupControlAdapter() + { + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::ConstructL +// 2nd phase constructor. Can leave. +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::ConstructL( CXnNodePluginIf& aNode ) + { + CXnControlAdapter::ConstructL( aNode ); + + iNode = &aNode.Node(); + iUiEngine = iNode->UiEngine(); + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::ProcessCommandL( TInt aCommandId ) + { + // Resolve selected item + for ( TInt i = 0; aCommandId != KErrCancel && i < iMenuItems.Count(); i++ ) + { + if ( i == aCommandId ) + { + // Do the actual item selection + iMenuItems[i]->SetStateL( + XnPropertyNames::style::common::KActive ); + + break; + } + } + + iMenuItems.Reset(); + iCommandId = 0; + + iMenuShown = EFalse; + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::SetEmphasis +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::SetEmphasis( CCoeControl* /*aMenuControl*/, + TBool /*aEmphasis*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::SetObserver +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::SetObserver( + XnMenuInterface::MXnMenuObserver& aObserver ) + { + iObserver = &aObserver; + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::TryDisplayingStylusPopupL +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::TryDisplayingStylusPopupL( CXnNode& aPlugin ) + { + HideMenuL(); + + TPointerEvent event( iUiEngine->HitTest().PointerEvent() ); + + delete iStylusPopupMenu; + iStylusPopupMenu = NULL; + + // Popup is positioned relatively to screen + iStylusPopupMenu = CAknStylusPopUpMenu::NewL( this, event.iParentPosition ); + + RPointerArray< CXnNode >& children( iNode->Children() ); + + for ( TInt i = 0; i < children.Count(); i++ ) + { + PopulateMenuL( children[i], aPlugin ); + } + + ShowMenuL( aPlugin, event.iParentPosition ); + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::HandleScreenDeviceChangedL +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::HandleScreenDeviceChangedL() + { + HideMenuL(); + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::PopulateMenuL +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::PopulateMenuL( CXnNode* aItem, CXnNode& aPlugin ) + { + CXnNode* menuitem( NULL ); + CXnProperty* prop( NULL ); + + TBool mappedItem( EFalse ); + + // Map widget menuitem first + if ( aItem->Type()->Type() == KWidgetMenuItem ) + { + // Widget menuitem is shown if a widget defined by the "aPlugin" + // defines a proper source - target menuitem pairing + CXnProperty* source( aItem->GetPropertyL( KSource ) ); + + if ( source ) + { + CXnNode* widgetItem( + FindWidgetMenuItemL( source->StringValue(), aPlugin ) ); + + if ( widgetItem ) + { + mappedItem = ETrue; + + // Get label from the view item + prop = aItem->LabelL(); + if ( !prop ) + { + // no localization in view, check from widget + prop = widgetItem->LabelL(); + } + // Pretend the original item is this widget item + aItem = widgetItem; + } + } + } + + const TDesC8& type( aItem->Type()->Type() ); + + if ( type == KMenuItem ) + { + // By default plain menuitems are always shown + menuitem = aItem; + } + else if ( type == KDynMenuItem && iObserver ) + { + // Let observer decide whether dynmenuitem is visible or not + if ( iObserver->DynInitMenuItemL( aItem->AppIfL(), &aPlugin.AppIfL() ) ) + { + menuitem = aItem; + } + } + + if ( menuitem ) + { + CXnProperty* display = menuitem->DisplayL(); + if ( display && display->StringValue() == XnPropertyNames::style::common::display::KNone ) + { + return; + } + + if ( !mappedItem ) + { + prop = menuitem->LabelL(); + } + + if ( prop ) + { + HBufC* label( prop->StringValueL() ); + CleanupStack::PushL( label ); + + iStylusPopupMenu->AddMenuItemL( *label, iCommandId++ ); + iMenuItems.AppendL( menuitem ); + + CleanupStack::PopAndDestroy( label ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::ShowMenuL +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::ShowMenuL( CXnNode& aPlugin, TPoint aPosition ) + { + if ( iMenuItems.Count() > 0 && !iMenuShown ) + { + iUiEngine->AppUiAdapter().HideFocus(); + + iUiEngine->Editor()->SetTargetPlugin( &aPlugin ); + + if ( AknLayoutUtils::LayoutMirrored() ) + { + iStylusPopupMenu->SetPosition( aPosition, + CAknStylusPopUpMenu::EPositionTypeRightBottom ); + } + else + { + iStylusPopupMenu->SetPosition( aPosition, + CAknStylusPopUpMenu::EPositionTypeLeftBottom ); + } + + iStylusPopupMenu->ShowMenu(); + iMenuShown = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CXnPopupControlAdapter::HideMenuL +// ----------------------------------------------------------------------------- +// +void CXnPopupControlAdapter::HideMenuL() + { + if ( iMenuShown ) + { + ProcessCommandL( KErrCancel ); + + delete iStylusPopupMenu; + iStylusPopupMenu = NULL; + + iMenuShown = EFalse; + } + } + +// End of file