idlehomescreen/xmluirendering/uiengine/src/xnpopupcontroladapter.cpp
changeset 0 f72a12da539e
child 9 f966699dea19
--- /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 <e32base.h>
+#include <e32const.h>
+#include <coecntrl.h>
+#include <AknUtils.h>
+#include <aknstyluspopupmenu.h>
+
+// 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 <widget> element from the <plugin> 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