uifw/AvKon/src/aknpointereventmodifier.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2008-2009 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 * Description:  Avkon pointer event modifier.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <aknpointereventmodifier.h>
       
    20 #include <coecntrl.h>
       
    21 
       
    22 // ======== MEMBER FUNCTIONS ========
       
    23 
       
    24 // ---------------------------------------------------------------------------
       
    25 // CAknPointerEventModifier::NewL
       
    26 // ---------------------------------------------------------------------------
       
    27 //
       
    28 CAknPointerEventModifier* CAknPointerEventModifier::NewL()
       
    29     {
       
    30     CAknPointerEventModifier* self = new ( ELeave ) CAknPointerEventModifier;
       
    31     return self;
       
    32     }
       
    33     
       
    34 // ---------------------------------------------------------------------------
       
    35 // CAknPointerEventModifier::~CAknPointerEventModifier()
       
    36 // ---------------------------------------------------------------------------
       
    37 //
       
    38 CAknPointerEventModifier::~CAknPointerEventModifier()
       
    39     {
       
    40     iStack.Close();
       
    41     }
       
    42     
       
    43 // ---------------------------------------------------------------------------
       
    44 // CAknPointerEventModifier::CAknPointerEventModifier
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 CAknPointerEventModifier::CAknPointerEventModifier()
       
    48     {
       
    49     }
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // CAknPointerEventModifier::Push
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 EXPORT_C void CAknPointerEventModifier::Push( CCoeControl& aControl, 
       
    56     const TRect& aRect )
       
    57     {
       
    58     // Figure out aControl's window-owning parent. This will also work as a
       
    59     // sanity check for the aControl argument.
       
    60     CCoeControl* parent = aControl.Parent();
       
    61     
       
    62     while ( parent && !parent->OwnsWindow() )
       
    63         {
       
    64         parent = parent->Parent();
       
    65         }
       
    66         
       
    67     if ( !parent )
       
    68         {
       
    69         return;
       
    70         }
       
    71     
       
    72     if ( !ControlIsInStack( aControl ) )
       
    73         {
       
    74         TStackItem item;
       
    75         item.iControl = &aControl;
       
    76         item.iParent = parent;
       
    77         item.iExtensionArea = aRect;
       
    78         
       
    79         if ( iStack.Insert( item, 0 ) == KErrNone )
       
    80             {
       
    81             iIsValid = EFalse;
       
    82             }
       
    83         }
       
    84     }
       
    85 
       
    86 // ---------------------------------------------------------------------------
       
    87 // CAknPointerEventModifier::Pop
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 EXPORT_C void CAknPointerEventModifier::Pop( const CCoeControl& aControl )
       
    91     {
       
    92     for ( TInt i = 0; i < iStack.Count(); ++i )
       
    93         {
       
    94         if ( iStack[i].iControl == &aControl )
       
    95             {
       
    96             iStack.Remove( i );
       
    97             iIsValid = EFalse;
       
    98             return;
       
    99             }
       
   100         }
       
   101     }
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 // CAknPointerEventModifier::Update
       
   105 // ---------------------------------------------------------------------------
       
   106 //
       
   107 EXPORT_C void CAknPointerEventModifier::Update( const CCoeControl& aControl, 
       
   108     const TRect& aRect )
       
   109     {
       
   110     for ( TInt i = 0; i < iStack.Count(); ++i )
       
   111         {
       
   112         if ( iStack[i].iControl == &aControl )
       
   113             {
       
   114             iStack[i].iExtensionArea = aRect;
       
   115             break;
       
   116             }
       
   117         }
       
   118     }
       
   119     
       
   120 // ---------------------------------------------------------------------------
       
   121 // CAknPointerEventModifier::HandlePointerEvent
       
   122 // ---------------------------------------------------------------------------
       
   123 //
       
   124 EXPORT_C void CAknPointerEventModifier::HandlePointerEvent( TPointerEvent& aEvent, 
       
   125     CCoeControl*& aDestination )
       
   126     {
       
   127     if ( iStack.Count() > 0 && aEvent.iType == TPointerEvent::EButton1Down )
       
   128         {
       
   129         if ( !iIsValid )
       
   130             {
       
   131             iStack.Sort( CAknPointerEventModifier::Compare );
       
   132             }
       
   133             
       
   134         for ( TInt i = 0; i < iStack.Count(); ++i )
       
   135             {
       
   136             if ( ModifyEvent( iStack[i], aEvent, aDestination ) )
       
   137                 {
       
   138                 break;
       
   139                 }
       
   140             }
       
   141         }
       
   142     }
       
   143     
       
   144 // ---------------------------------------------------------------------------
       
   145 // CAknPointerEventModifier::Invalidate
       
   146 // ---------------------------------------------------------------------------
       
   147 //
       
   148 void CAknPointerEventModifier::Invalidate()
       
   149     {
       
   150     iIsValid = ETrue;
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // CAknPointerEventModifier::ControlIsInStack
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 TBool CAknPointerEventModifier::ControlIsInStack( const CCoeControl& aControl )
       
   158     {
       
   159     for ( TInt i = 0; i < iStack.Count(); ++i )
       
   160         {
       
   161         if ( iStack[i].iControl == &aControl )
       
   162             {
       
   163             return ETrue;
       
   164             }
       
   165         }
       
   166     
       
   167     return EFalse;
       
   168     }
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // CAknPointerEventModifier::ModifyEvent
       
   172 // ---------------------------------------------------------------------------
       
   173 //
       
   174 TBool CAknPointerEventModifier::ModifyEvent( TStackItem& aItem, 
       
   175     TPointerEvent& aEvent, CCoeControl*& aDestination )
       
   176     {
       
   177     TBool wasModified = EFalse;
       
   178     
       
   179     // Control window's existence has been checked already in 
       
   180     // CAknPointerEventModifier::Push.
       
   181     if ( !aItem.iControl->DrawableWindow()->IsFaded() )
       
   182         {
       
   183         TBool isVertical = ( aItem.iControl->Size().iHeight > aItem.iControl->Size().iWidth );
       
   184         
       
   185         if ( aDestination == aItem.iParent )
       
   186             {
       
   187             // calculate hit area
       
   188             TRect hitArea( aItem.iControl->Position() + 
       
   189                 aItem.iExtensionArea.iTl, aItem.iExtensionArea.Size() );
       
   190             TSize controlSize( aItem.iControl->Size() );
       
   191 
       
   192             if ( hitArea.Contains( aEvent.iPosition ) )
       
   193                 {
       
   194                 if ( aItem.iControl->OwnsWindow() )
       
   195                     {
       
   196                     aDestination = aItem.iControl;
       
   197                     
       
   198                     if ( isVertical )
       
   199                         {
       
   200                         aEvent.iPosition.iX = controlSize.iWidth >> 1;
       
   201                         aEvent.iPosition.iY -= aItem.iControl->Position().iY;
       
   202                         }
       
   203                     else
       
   204                         {
       
   205                         aEvent.iPosition.iX -= aItem.iControl->Position().iX;
       
   206                         aEvent.iPosition.iY = controlSize.iHeight >> 1;
       
   207                         }
       
   208                     }
       
   209                 else
       
   210                     {
       
   211                     if ( isVertical )
       
   212                         {
       
   213                         aEvent.iPosition.iX = aItem.iControl->Position().iX + 
       
   214                             ( controlSize.iWidth >> 1 );
       
   215                         }
       
   216                     else
       
   217                         {
       
   218                         aEvent.iPosition.iY = aItem.iControl->Position().iY +
       
   219                             ( controlSize.iHeight >> 1 );
       
   220                         }
       
   221                     }
       
   222                     
       
   223                 wasModified = ETrue;
       
   224                 }
       
   225             }
       
   226         else if ( aDestination->Parent() && 
       
   227             aDestination->Parent()->DrawableWindow() == aItem.iParent->DrawableWindow() &&
       
   228              ( aDestination->Parent() != aItem.iParent ))
       
   229             {
       
   230             // This branch handles external scrollbars. It should be checked
       
   231             // via MOP chain if the aItem.iControl really is a scrollbar before
       
   232             // this API is taken into use with other controls.
       
   233             TPoint topLeft( aItem.iControl->Position().iX - 
       
   234                 aDestination->Position().iX, 
       
   235                 aItem.iControl->Position().iY - aDestination->Position().iY );
       
   236             TRect hitArea( topLeft + 
       
   237                 aItem.iExtensionArea.iTl, aItem.iExtensionArea.Size() );
       
   238 
       
   239             if ( hitArea.Contains( aEvent.iPosition ) )
       
   240                 {
       
   241                 TInt controlPosition = aItem.iControl->Position().iY;
       
   242                 TInt positionInParent = aEvent.iPosition.iY + aDestination->Position().iY;
       
   243                 
       
   244                 if ( isVertical )
       
   245                     {
       
   246                     aEvent.iPosition.iX = aItem.iControl->Size().iWidth >> 1;
       
   247                     aEvent.iPosition.iY = positionInParent - controlPosition;
       
   248                     }
       
   249                 else
       
   250                     {
       
   251                     aEvent.iPosition.iX = aEvent.iPosition.iX + 
       
   252                         aDestination->Position().iX - aItem.iControl->Position().iX;
       
   253                     aEvent.iPosition.iY = aItem.iControl->Size().iHeight >> 1;
       
   254                     }
       
   255                     
       
   256                 aDestination = aItem.iControl;
       
   257                 
       
   258                 wasModified = ETrue;
       
   259                 }
       
   260             }
       
   261         }
       
   262         
       
   263     return wasModified;
       
   264     }
       
   265     
       
   266 // ---------------------------------------------------------------------------
       
   267 // CAknPointerEventModifier::Compare
       
   268 // ---------------------------------------------------------------------------
       
   269 //
       
   270 TInt CAknPointerEventModifier::Compare( const TStackItem& aFirst, 
       
   271     const TStackItem& aSecond )
       
   272     {
       
   273     TInt retval = -1; // aFirst is in front of aSecond
       
   274     TInt firstPosition = aFirst.iParent->DrawableWindow()->OrdinalPosition();
       
   275     TInt secondPosition = aSecond.iParent->DrawableWindow()->OrdinalPosition();
       
   276     
       
   277     if ( secondPosition < firstPosition && secondPosition >= 0 )
       
   278         {
       
   279         // aSecond is in front of aFirst in z-order
       
   280         retval = 1;
       
   281         }
       
   282     else if ( firstPosition == secondPosition )
       
   283         {
       
   284         // aFirst and aSecond have the same parent window
       
   285         retval = 0;
       
   286         }
       
   287     
       
   288     return retval;
       
   289     }