idlehomescreen/xmluirendering/uiengine/src/xnwidgetextensionadapter.cpp
changeset 0 f72a12da539e
child 2 08c6ee43b396
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 */
       
    15 
       
    16 
       
    17 #include <e32base.h>
       
    18 #include <e32const.h>
       
    19 #include <coecntrl.h>
       
    20 #include <coemain.h>
       
    21 
       
    22 #include <AknUtils.h>
       
    23 
       
    24 #include "xnwidgetextensionadapter.h"
       
    25 #include "xncontroladapter.h"
       
    26 
       
    27 #include "xncomponentnodeimpl.h"
       
    28 #include "xncomponent.h"
       
    29 
       
    30 #include "xnuiengine.h"
       
    31 #include "xnhittest.h"
       
    32 
       
    33 #include "xnnode.h"
       
    34 #include "xnnodepluginif.h"
       
    35 #include "xnviewnodeimpl.h"
       
    36 #include "xnnodepluginif.h"
       
    37 #include "xndomdocument.h"
       
    38 #include "xnproperty.h"
       
    39 #include "xnodt.h"  
       
    40 #include "xntype.h"
       
    41 #include "xndomnode.h"
       
    42 #include "xndomstringpool.h"
       
    43 
       
    44 #include "xnappuiadapter.h"
       
    45 #include "xnviewmanager.h"
       
    46 #include "xnviewdata.h"
       
    47 #include "xnplugindata.h"
       
    48 
       
    49 
       
    50 _LIT8( KPopUpText, "popup" );
       
    51 _LIT8( KPositionHint, "_s60-position-hint" );
       
    52 _LIT8( KWidgetNodeName, "widget" );
       
    53 _LIT8( KParentIdName, "parentid" );
       
    54 _LIT8( KDisplay, "display" );
       
    55 _LIT8( KNone, "none" );
       
    56 // ============================ MEMBER FUNCTIONS ===============================
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CXnWidgetExtensionAdapter::NewL
       
    60 // Two-phased constructor. Can leave.
       
    61 // -----------------------------------------------------------------------------
       
    62 //
       
    63 CXnWidgetExtensionAdapter* CXnWidgetExtensionAdapter::NewL( 
       
    64     CXnNodePluginIf& aNode )
       
    65     {
       
    66     CXnWidgetExtensionAdapter* self = 
       
    67         new ( ELeave ) CXnWidgetExtensionAdapter( aNode );
       
    68     CleanupStack::PushL( self );
       
    69     self->ConstructL();
       
    70     CleanupStack::Pop( self );
       
    71     return self;
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CXnWidgetExtensionAdapter::~CXnWidgetExtensionAdapter
       
    76 // Destructor.
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CXnWidgetExtensionAdapter::~CXnWidgetExtensionAdapter()
       
    80     {
       
    81     }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CXnWidgetExtensionAdapter::CXnWidgetExtensionAdapter
       
    85 // C++ default constructor. Must not leave.
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 CXnWidgetExtensionAdapter::CXnWidgetExtensionAdapter( CXnNodePluginIf& aNode )
       
    89     : iNode( aNode ), iPositionHint( ENone )
       
    90     {
       
    91     }
       
    92 
       
    93 // -----------------------------------------------------------------------------
       
    94 // CXnWidgetExtensionAdapter::ConstructL
       
    95 // 2nd phase constructor. Can leave.
       
    96 // -----------------------------------------------------------------------------
       
    97 //    
       
    98 void CXnWidgetExtensionAdapter::ConstructL()
       
    99     {
       
   100     CreateWindowL();
       
   101     Window().SetRequiredDisplayMode( EColor16MA );
       
   102 
       
   103     // this adapter handles both widgetextension and popup nodes
       
   104     // we have to decide which one of them is the recent one    
       
   105  
       
   106     CXnType* typeInfo = iNode.Node().Type();
       
   107     const TDesC8& type = typeInfo->Type();
       
   108 
       
   109     if ( type == KPopUpText )
       
   110         {
       
   111         // popup element does not capture pointer events
       
   112         SetPointerCapture( ETrue );      
       
   113         }
       
   114     else
       
   115         {
       
   116         // widget extension node
       
   117         SetPointerCapture( ETrue );
       
   118         if ( Window().SetTransparencyAlphaChannel() == KErrNone )
       
   119             {
       
   120             Window().SetBackgroundColor( ~0 );
       
   121             }     
       
   122         }
       
   123     iUiEngine = iNode.Node().UiEngine();
       
   124     CXnControlAdapter::ConstructL( iNode );
       
   125     EnableDragEvents();   
       
   126 
       
   127     iAppUiAdapter = static_cast< CXnAppUiAdapter* >( iAvkonAppUi );
       
   128 
       
   129     }
       
   130 
       
   131 // -----------------------------------------------------------------------------
       
   132 // CXnWidgetExtensionAdapter::MakeVisible
       
   133 // 
       
   134 // -----------------------------------------------------------------------------
       
   135 // 
       
   136 void CXnWidgetExtensionAdapter::MakeVisible( TBool aVisible )
       
   137     {
       
   138    
       
   139     TBool visible( IsVisible() ? ETrue : EFalse );
       
   140     if ( visible == aVisible )
       
   141         {
       
   142         return;
       
   143         }
       
   144 
       
   145     CXnPluginData& plugin( 
       
   146             iAppUiAdapter->ViewManager().ActiveViewData().Plugin( &iNode.Node() ) );
       
   147 
       
   148     plugin.SetIsDisplayingPopup( aVisible, &iNode.Node() );
       
   149     
       
   150     if ( aVisible )
       
   151         {
       
   152         
       
   153         CXnType* typeInfo = iNode.Node().Type();
       
   154         const TDesC8& type = typeInfo->Type();
       
   155 
       
   156         if ( type == KPopUpText )
       
   157             {            
       
   158             // read position-hint property and set-up its variable
       
   159             CXnProperty* positionHintProp = NULL;
       
   160             TRAP_IGNORE( positionHintProp = iNode.Node().GetPropertyL( KPositionHint ) );
       
   161                        
       
   162             if ( positionHintProp )
       
   163                 {
       
   164                 const TDesC8& displayHintVal = positionHintProp->StringValue();
       
   165                         
       
   166                 if ( displayHintVal == XnPropertyNames::tooltip::positionhint::KAboveLeft )
       
   167                     {
       
   168                     iPositionHint = EAboveLeft;
       
   169                     }
       
   170                 else if ( displayHintVal == XnPropertyNames::tooltip::positionhint::KAboveRight )
       
   171                     {
       
   172                     iPositionHint = EAboveRight;
       
   173                     }
       
   174                 else if ( displayHintVal == XnPropertyNames::tooltip::positionhint::KBelowLeft )
       
   175                     {
       
   176                     iPositionHint = EBelowLeft;
       
   177                     }
       
   178                 else if ( displayHintVal == XnPropertyNames::tooltip::positionhint::KBelowRight )
       
   179                     {
       
   180                     iPositionHint = EBelowRight;
       
   181                     }
       
   182                 else if ( displayHintVal == XnPropertyNames::tooltip::positionhint::KRight )
       
   183                     {
       
   184                     iPositionHint = ERight;
       
   185                     }
       
   186                 else if ( displayHintVal == XnPropertyNames::tooltip::positionhint::KLeft )
       
   187                     {
       
   188                     iPositionHint = ELeft;
       
   189                     }
       
   190                 else 
       
   191                     {
       
   192                      // if the value if of unknown type, use default one
       
   193                      if ( AknLayoutUtils::LayoutMirrored() )
       
   194                          {
       
   195                          iPositionHint = EAboveRight;
       
   196                          }
       
   197                          else
       
   198                          {
       
   199                          iPositionHint = EAboveLeft; 
       
   200                          }
       
   201                      }
       
   202             
       
   203                 if ( iPositionHint != ENone )
       
   204                     {    
       
   205                     // the popup is going visible and position-hind is available
       
   206                     // calculate its position
       
   207                     CalculatePosition();
       
   208                     }
       
   209                 }
       
   210             }       
       
   211         DrawableWindow()->FadeBehind( ETrue );
       
   212         }
       
   213     else
       
   214         {
       
   215         DrawableWindow()->FadeBehind( EFalse );
       
   216         }
       
   217     CCoeControl::MakeVisible( aVisible );            
       
   218     }
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // CXnWidgetExtensionAdapter::HandlePointerEventL
       
   222 // 
       
   223 // -----------------------------------------------------------------------------
       
   224 //    
       
   225 void CXnWidgetExtensionAdapter::HandlePointerEventL( 
       
   226     const TPointerEvent& aPointerEvent )
       
   227     {    
       
   228     
       
   229     CXnType* typeInfo = iNode.Node().Type();
       
   230     const TDesC8& type = typeInfo->Type();
       
   231     
       
   232     // in case of popup, we have to make sure that 
       
   233     // it will be closed after tapping outside of the
       
   234     // area of itself and its parent
       
   235     if ( type == KPopUpText )
       
   236         {
       
   237         
       
   238         // check if the tap was inside of popup
       
   239         TRect popupRect = this->Rect();
       
   240         popupRect.Move(this->Position() );
       
   241         TBool isInPopupWindow = popupRect.Contains(
       
   242                 aPointerEvent.iParentPosition );
       
   243 
       
   244         if ( !isInPopupWindow )
       
   245             {
       
   246             
       
   247             // if tap was outside of window, check if tap was 
       
   248             // inside of the parrent
       
   249             CXnProperty* parentIdProp = iNode.Node().GetPropertyL(
       
   250                     KParentIdName );
       
   251             
       
   252             if ( parentIdProp )
       
   253                 {                
       
   254                 const TDesC8& parentIdVal = parentIdProp->StringValue();
       
   255                 CXnNode* parentN(iUiEngine->FindNodeByIdL( parentIdVal,
       
   256                         iNode.Node().Namespace() ) );
       
   257                 
       
   258                 TRect clientRect =
       
   259                         static_cast<CEikAppUi&> ( *iAppUiAdapter ).ClientRect();
       
   260                 TRect parentRect = parentN->Rect();
       
   261                 parentRect.Move( clientRect.iTl );
       
   262                 
       
   263                 if ( !parentRect.Contains( aPointerEvent.iParentPosition ) )
       
   264                     {
       
   265                     // tap was neither in popup nor in its parent -
       
   266                     // we can close it
       
   267                     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   268                         {
       
   269                         CXnDomStringPool& sp =
       
   270                             iNode.Node().DomNode()->StringPool();
       
   271                         CXnProperty* prop = CXnProperty::NewL( KDisplay, KNone,
       
   272                         CXnDomPropertyValue::EString, sp );
       
   273                         CleanupStack::PushL( prop );
       
   274                         iNode.Node().SetPropertyL( prop );
       
   275                         CleanupStack::Pop( prop );
       
   276                         return;
       
   277                         }
       
   278                     }
       
   279                 else
       
   280                     {
       
   281                     // tap was made inside of popup parent
       
   282                     // we pass the event to it after
       
   283                     // recalculating the taping point
       
   284                     TPointerEvent newPointerEvent;
       
   285                     newPointerEvent.Copy( aPointerEvent );
       
   286                     newPointerEvent.iPosition = TPoint(
       
   287                              aPointerEvent.iParentPosition - clientRect.iTl );
       
   288                     parentN->Control()->HandlePointerEventL( newPointerEvent );
       
   289                     return;
       
   290                     }
       
   291                 }
       
   292             }
       
   293         }
       
   294     
       
   295     CXnControlAdapter::HandlePointerEventL( aPointerEvent );
       
   296     
       
   297     }
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CXnWidgetExtensionAdapter::Draw
       
   301 // 
       
   302 // -----------------------------------------------------------------------------
       
   303 //    
       
   304 void CXnWidgetExtensionAdapter::Draw( const TRect& aRect ) const
       
   305     {
       
   306         CXnControlAdapter::Draw( aRect );
       
   307     }
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 // CalculatePosition
       
   311 // This is used only for popup element with position hint
       
   312 // -----------------------------------------------------------------------------
       
   313 void CXnWidgetExtensionAdapter::CalculatePosition() 
       
   314     {
       
   315 
       
   316     // widget's rectangle
       
   317     TRect controlRect;
       
   318 
       
   319     // get popup's window size
       
   320     TRect popupRect = this->Rect();
       
   321 
       
   322     TRect clientRect = static_cast<CEikAppUi&>( *iAppUiAdapter ).ClientRect();
       
   323 
       
   324     // get entire screen except control pane
       
   325     TRect contentRect( 0, 0, clientRect.iBr.iX, clientRect.iBr.iY ); 
       
   326 
       
   327     // resulting rectangle
       
   328     TRect rect;
       
   329 
       
   330     TPoint offset( clientRect.iTl );
       
   331 
       
   332     // parent widget's rectangle ( first predecesscor which is "widget" )
       
   333     CXnNode* parent = iNode.Node().Parent();
       
   334 
       
   335     while ( parent )
       
   336         {
       
   337         const TDesC8& type( parent->DomNode()->Name() );
       
   338         if ( type == KWidgetNodeName )
       
   339             {
       
   340             break;
       
   341             }
       
   342         parent = parent->Parent();
       
   343         }
       
   344     
       
   345     // if predecesscor widget was not found, use parent's rectangle
       
   346     if ( parent == NULL )
       
   347         { 
       
   348         controlRect = iNode.Node().Parent()->Rect();
       
   349         }
       
   350     else
       
   351         {
       
   352         controlRect = parent->BorderRect();
       
   353         }
       
   354     
       
   355     // calculate available space for placing the popup
       
   356     TInt spaceAbove = controlRect.iTl.iY + offset.iY;
       
   357     TInt spaceBelow = contentRect.iBr.iY - controlRect.iBr.iY - offset.iY;
       
   358     TInt spaceLeft = controlRect.iTl.iX + offset.iX;
       
   359     TInt spaceRight = contentRect.iBr.iX - controlRect.iBr.iX - offset.iX;
       
   360 
       
   361     switch ( iPositionHint )
       
   362         {
       
   363         
       
   364         case EAboveLeft:
       
   365             
       
   366             // if this position does not fit the screen,
       
   367             // and if below left is more suitable, use it
       
   368             if ( spaceAbove < popupRect.Height() && spaceBelow > spaceAbove )
       
   369                 {
       
   370                 rect = TRect( TPoint( controlRect.iTl.iX, controlRect.iBr.iY ), 
       
   371                               TPoint( controlRect.iTl.iX + popupRect.Width(), controlRect.iBr.iY + popupRect.Height() ) );
       
   372                 }
       
   373             else
       
   374                 {
       
   375                 // use the above-left position
       
   376                 rect = TRect( TPoint( controlRect.iTl.iX, controlRect.iTl.iY - popupRect.Height() ), 
       
   377                               TPoint( controlRect.iTl.iX + popupRect.Width(), controlRect.iTl.iY ) );
       
   378                 
       
   379                 }
       
   380             break;
       
   381             
       
   382         case EAboveRight:
       
   383             
       
   384             // if this position does not fit the screen,
       
   385             // and if below right is more suitable, use it
       
   386             if ( spaceAbove < popupRect.Height() && spaceBelow > spaceAbove )
       
   387                 {
       
   388                 rect = TRect( TPoint( controlRect.iBr.iX - popupRect.Width(), controlRect.iBr.iY ), 
       
   389                               TPoint( controlRect.iBr.iX, controlRect.iBr.iY + popupRect.Height() ) );
       
   390                 }
       
   391             else
       
   392                 {
       
   393                 // use the above-right position
       
   394                 rect = TRect( TPoint( controlRect.iBr.iX - popupRect.Width(), controlRect.iTl.iY - popupRect.Height() ), 
       
   395                               TPoint( controlRect.iBr.iX,  controlRect.iTl.iY ) );
       
   396                 }
       
   397             break;
       
   398             
       
   399         case EBelowLeft:
       
   400             
       
   401             // if this position does not fit the screen,
       
   402             // and if above left is more suitable, use it
       
   403             if ( spaceBelow < popupRect.Height() && spaceBelow < spaceAbove )
       
   404                 {
       
   405                 rect = TRect( TPoint( controlRect.iTl.iX, controlRect.iTl.iY - popupRect.Height() ), 
       
   406                               TPoint( controlRect.iTl.iX + popupRect.Width(), controlRect.iTl.iY ) );
       
   407                 }
       
   408             else
       
   409                 {
       
   410                 // use the below-left position
       
   411                 rect = TRect( TPoint( controlRect.iTl.iX, controlRect.iBr.iY ), 
       
   412                               TPoint( controlRect.iTl.iX + popupRect.Width(), controlRect.iBr.iY + popupRect.Height() ) );
       
   413                 }
       
   414             break;
       
   415 
       
   416         case EBelowRight:
       
   417 
       
   418               // if this position does not fit the screen,
       
   419               // and if above right is more suitable, use it
       
   420               if ( spaceBelow < popupRect.Height() && spaceBelow < spaceAbove )
       
   421                   {
       
   422                   rect = TRect( TPoint( controlRect.iBr.iX - popupRect.Width(), controlRect.iTl.iY - popupRect.Height() ), 
       
   423                                 TPoint( controlRect.iBr.iX,  controlRect.iTl.iY ) );
       
   424                   }
       
   425               else
       
   426                   {
       
   427                   // use the below-right position
       
   428                   rect = TRect( TPoint( controlRect.iBr.iX - popupRect.Width(), controlRect.iBr.iY ), 
       
   429                                 TPoint( controlRect.iBr.iX, controlRect.iBr.iY + popupRect.Height() ) );
       
   430                   }
       
   431             break;
       
   432 
       
   433         case ERight:
       
   434 
       
   435             // if this position does not fit the screen,
       
   436             // and if left or above-left is more suitable, use it
       
   437             if ( spaceRight < popupRect.Width() )
       
   438                 {
       
   439                 // use the left position if the space is big enough
       
   440                 if ( spaceLeft >= popupRect.Width() )
       
   441                     {
       
   442                     // use left position
       
   443                     rect = TRect( TPoint( controlRect.iTl.iX - popupRect.Width(), controlRect.iTl.iY ), 
       
   444                                   TPoint( controlRect.iTl.iX, controlRect.iTl.iY + popupRect.Height() ) );
       
   445                     }
       
   446                 else if ( spaceAbove >= popupRect.Height() )
       
   447                     {
       
   448                     // use the above-right position
       
   449                     rect = TRect( TPoint( controlRect.iBr.iX - popupRect.Width(), controlRect.iTl.iY - popupRect.Height() ), 
       
   450                                   TPoint( controlRect.iBr.iX,  controlRect.iTl.iY ) );  
       
   451                     }
       
   452                 else
       
   453                     {
       
   454                     // use the below-right position
       
   455                     rect = TRect( TPoint( controlRect.iBr.iX - popupRect.Width(), controlRect.iBr.iY ), 
       
   456                                   TPoint( controlRect.iBr.iX, controlRect.iBr.iY + popupRect.Height() ) );
       
   457                     }
       
   458                 }
       
   459             else
       
   460                 {
       
   461                 // use the right position
       
   462                 rect = TRect( TPoint( controlRect.iBr.iX, controlRect.iTl.iY ), 
       
   463                               TPoint( controlRect.iBr.iX + popupRect.Width(), controlRect.iTl.iY + popupRect.Height() ) );
       
   464                 }
       
   465                 
       
   466             break;
       
   467             
       
   468         case ELeft:
       
   469             
       
   470             // if this position does not fit the screen,
       
   471             // and if right is more suitable, use it
       
   472             if ( spaceLeft < popupRect.Width() )
       
   473                 {
       
   474                 // use the right position, if it the space is big enough
       
   475                 if ( spaceRight >= popupRect.Width() )
       
   476                     {    
       
   477                     rect = TRect( TPoint( controlRect.iBr.iX, controlRect.iTl.iY ), 
       
   478                                   TPoint( controlRect.iBr.iX + popupRect.Width(), controlRect.iTl.iY + popupRect.Height() ) );
       
   479                     }
       
   480                 else if ( spaceAbove >= popupRect.Height() )
       
   481                     {
       
   482                     // use the above-left position
       
   483                     rect = TRect( TPoint( controlRect.iTl.iX, controlRect.iTl.iY - popupRect.Height() ), 
       
   484                                   TPoint( controlRect.iTl.iX + popupRect.Width(), controlRect.iTl.iY ) );
       
   485                     }
       
   486                 else
       
   487                     {
       
   488                     // use the below-left position
       
   489                     rect = TRect( TPoint( controlRect.iTl.iX, controlRect.iBr.iY ), 
       
   490                                   TPoint( controlRect.iTl.iX + popupRect.Width(), controlRect.iBr.iY + popupRect.Height() ) );
       
   491                     }
       
   492                 }
       
   493             else
       
   494                 {
       
   495                 // use the left position  
       
   496                 rect = TRect( TPoint( controlRect.iTl.iX - popupRect.Width(), controlRect.iTl.iY ), 
       
   497                               TPoint( controlRect.iTl.iX, controlRect.iTl.iY + popupRect.Height() ) );
       
   498                 }
       
   499             break;
       
   500         default:
       
   501             break;
       
   502         }
       
   503 
       
   504     rect.Move( offset );
       
   505 
       
   506     // if the popup rectangle exceeds the borders of content rectangle, move it.
       
   507     if ( rect.iTl.iY < contentRect.iTl.iY )
       
   508         {
       
   509         rect.Move( 0, contentRect.iTl.iY - rect.iTl.iY );
       
   510         }
       
   511     if ( rect.iTl.iX < contentRect.iTl.iX )
       
   512         {
       
   513         rect.Move( contentRect.iTl.iX - rect.iTl.iX, 0 );
       
   514         }
       
   515     if ( rect.iBr.iY > contentRect.iBr.iY )
       
   516         {
       
   517         rect.Move( 0, contentRect.iBr.iY - rect.iBr.iY );
       
   518         }
       
   519     if ( rect.iBr.iX > contentRect.iBr.iX )
       
   520         {
       
   521         rect.Move( contentRect.iBr.iX - rect.iBr.iX, 0 );
       
   522         }
       
   523     this->SetRect( rect );
       
   524     }
       
   525 
       
   526 //  End of File