--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluirendering/uiengine/src/xnpopupcontroladapter.cpp Wed Sep 01 12:32:46 2010 +0100
@@ -0,0 +1,372 @@
+/*
+* 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 <e32base.h>
+#include <e32const.h>
+#include <coecntrl.h>
+#include <aknstyluspopupmenu.h>
+
+// User includes
+#include "xnappuiadapter.h"
+#include "xnviewadapter.h"
+#include "xnkeyeventdispatcher.h"
+#include "xnviewmanager.h"
+#include "xnviewdata.h"
+#include "xnplugindata.h"
+#include "xnproperty.h"
+#include "xncontroladapter.h"
+#include "xndomnode.h"
+#include "xnnodepluginif.h"
+#include "xnnode.h"
+#include "xntype.h"
+#include "xnuiengine.h"
+#include "xneditor.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
+//
+// -----------------------------------------------------------------------------
+//
+static CXnNode* FindWidgetMenuItemL( CXnPluginData& aPlugin,
+ const TDesC8& aSource )
+ {
+ if ( !aPlugin.Occupied() )
+ {
+ return NULL;
+ }
+
+ CXnNode* widget( aPlugin.Node()->LayoutNode() );
+
+ RPointerArray< CXnNode >& children( widget->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();
+
+ iMenuShown = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// 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;
+ }
+ }
+
+ iUiEngine->Editor()->SetTargetPlugin( NULL );
+
+ 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();
+
+ CXnViewManager* manager( iUiEngine->ViewManager() );
+ CXnPluginData* plugin( manager->ActiveViewData().Plugin( &aPlugin ) );
+
+ if ( !plugin )
+ {
+ return;
+ }
+
+ CXnViewAdapter& adapter( iUiEngine->AppUiAdapter().ViewAdapter() );
+
+ const TPointerEvent& event( adapter.EventDispatcher()->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( *plugin, children[i] );
+ }
+
+ ShowMenuL( *plugin, event.iParentPosition );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnPopupControlAdapter::HandleScreenDeviceChangedL
+// -----------------------------------------------------------------------------
+//
+void CXnPopupControlAdapter::HandleScreenDeviceChangedL()
+ {
+ HideMenuL();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnPopupControlAdapter::PopulateMenuL
+// -----------------------------------------------------------------------------
+//
+void CXnPopupControlAdapter::PopulateMenuL( CXnPluginData& aPlugin,
+ CXnNode* aItem )
+ {
+ 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( aPlugin, source->StringValue() ) );
+
+ 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 )
+ {
+ CXnNode* plugin( aPlugin.Owner()->LayoutNode() );
+
+ // Let observer decide whether dynmenuitem is visible or not
+ if ( iObserver->DynInitMenuItemL( aItem->AppIfL(), &plugin->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( CXnPluginData& aPlugin,
+ TPoint aPosition )
+ {
+ if ( iMenuItems.Count() > 0 && !iMenuShown )
+ {
+ iUiEngine->AppUiAdapter().HideFocus();
+
+ CXnNode* plugin( aPlugin.Owner()->LayoutNode() );
+
+ iUiEngine->Editor()->SetTargetPlugin( plugin );
+
+ iStylusPopupMenu->SetPosition( aPosition,
+ CAknStylusPopUpMenu::EPositionTypeRightBottom );
+
+ iStylusPopupMenu->ShowMenu();
+ iMenuShown = ETrue;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnPopupControlAdapter::HideMenuL
+// -----------------------------------------------------------------------------
+//
+void CXnPopupControlAdapter::HideMenuL()
+ {
+ if ( iMenuShown )
+ {
+ ProcessCommandL( KErrCancel );
+
+ delete iStylusPopupMenu;
+ iStylusPopupMenu = NULL;
+
+ iMenuShown = EFalse;
+ }
+ }
+
+
+// End of file