phoneuis/dialer/src/cdialertoolbarcontainer.cpp
branchRCL_3
changeset 9 8871b09be73b
child 15 2a26698d78ba
equal deleted inserted replaced
4:c84cf270c54f 9:8871b09be73b
       
     1 /*
       
     2 * Copyright (c) 2009, 2010 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:  CDialerToolbarContainer replaces the standard S60 toolbar
       
    15 *               in the Dialer layout in the Easy dialing mode. It's 
       
    16 *               responsible of the toolbar layout and logic, but not of the 
       
    17 *               contents which are provided by an instance of 
       
    18 *               MPhoneDialerController.
       
    19 *
       
    20 */
       
    21 
       
    22 #include <aknbutton.h>
       
    23 #include <aknappui.h>
       
    24 #include <AknsUtils.h>
       
    25 #include <aknlayoutscalable_apps.cdl.h>
       
    26 #include <layoutmetadata.cdl.h>
       
    27 #include <phoneui.rsg>
       
    28 #include <phoneappcommands.hrh>
       
    29 #include <StringLoader.h>
       
    30 #include <data_caging_path_literals.hrh>
       
    31 
       
    32 #include "dialercommon.h"
       
    33 #include "cdialertoolbarcontainer.h"
       
    34 
       
    35 
       
    36 // CONSTANTS
       
    37 const TInt KDialerToolbarButtonKeyRepeatDelay = 300;
       
    38 const TInt KDialerToolbarKeyRepeatInterval = 75;
       
    39 
       
    40 
       
    41 
       
    42 // CLASS DEFINITION
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // NewL
       
    46 //
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 CDialerToolbarContainer* CDialerToolbarContainer::NewL( CCoeControl& aParent,
       
    50         MPhoneDialerController* aContentProvider )
       
    51     {
       
    52     CDialerToolbarContainer* self = 
       
    53             new (ELeave) CDialerToolbarContainer( aParent, aContentProvider );
       
    54     CleanupStack::PushL( self );
       
    55     self->ConstructL();
       
    56     CleanupStack::Pop( self );
       
    57     return self;
       
    58     }
       
    59 
       
    60 // ---------------------------------------------------------------------------
       
    61 // CDialerToolbarContainer
       
    62 //
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CDialerToolbarContainer::CDialerToolbarContainer( CCoeControl& aParent,
       
    66         MPhoneDialerController* aContentProvider ) : 
       
    67     CDialerContainerBase( aParent ), 
       
    68     iContentProvider( aContentProvider )
       
    69     {
       
    70     }
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 // ~CDialerToolbarContainer
       
    74 //
       
    75 // ---------------------------------------------------------------------------
       
    76 //
       
    77 CDialerToolbarContainer::~CDialerToolbarContainer()
       
    78     {
       
    79     iCoeEnv->RemoveForegroundObserver( *this );
       
    80     DeleteButtons();
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // ConstructL
       
    85 //
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 void CDialerToolbarContainer::ConstructL()
       
    89     {
       
    90     BaseConstructL();
       
    91     
       
    92     CreateButtonsL();
       
    93 
       
    94     iCoeEnv->AddForegroundObserverL( *this );
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 // SetContentProviderL
       
    99 //
       
   100 // ---------------------------------------------------------------------------
       
   101 //
       
   102 void CDialerToolbarContainer::SetContentProviderL( MPhoneDialerController* aProvider )
       
   103     {
       
   104     if ( iContentProvider != aProvider )
       
   105         {
       
   106         iContentProvider = aProvider;
       
   107         
       
   108         // Recreate buttons to reset available button states
       
   109         DeleteButtons();
       
   110         CreateButtonsL();
       
   111         }
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // UpdateButtonStates
       
   116 //
       
   117 // ---------------------------------------------------------------------------
       
   118 //
       
   119 void CDialerToolbarContainer::UpdateButtonStates()
       
   120     {
       
   121     // safety check
       
   122     if ( iButtons.Count() < MPhoneDialerController::ENumberOfButtons ||
       
   123          !iContentProvider )
       
   124         {
       
   125         return;
       
   126         }
       
   127     
       
   128     for ( TInt i = 0 ; i < MPhoneDialerController::ENumberOfButtons ; ++i )
       
   129         {
       
   130         MPhoneDialerController::TButtonIndex idx =
       
   131             static_cast< MPhoneDialerController::TButtonIndex >( i );
       
   132         TInt state = iContentProvider->ButtonState( idx );
       
   133         TBool dimmed = iContentProvider->ButtonDimmed( idx );
       
   134         if ( state >= 0 )
       
   135             {
       
   136             iButtons[i]->SetCurrentState( state, EFalse );
       
   137             }
       
   138         iButtons[i]->SetDimmed( dimmed );
       
   139         }
       
   140     }
       
   141 
       
   142 // ---------------------------------------------------------------------------
       
   143 // SetVariety
       
   144 //
       
   145 // ---------------------------------------------------------------------------
       
   146 //
       
   147 void CDialerToolbarContainer::SetVariety()
       
   148     {
       
   149     iVariety = ( Layout_Meta_Data::IsLandscapeOrientation() ?
       
   150         EDialerVarietyLandscape : EDialerVarietyPortrait );
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // SetLayout
       
   155 //
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 void CDialerToolbarContainer::SetLayout()
       
   159     {
       
   160     if ( iButtons.Count() < MPhoneDialerController::ENumberOfButtons )
       
   161         {
       
   162         return;
       
   163         }
       
   164     
       
   165     // Position for the first button
       
   166     TPoint buttonPos = Rect().iTl;
       
   167     
       
   168     if ( iVariety == EDialerVarietyPortrait )
       
   169         {
       
   170         // In portrait, buttons are laid out from top to bottom
       
   171         for ( TInt i = 0 ; i < iButtons.Count() ; ++i )
       
   172             {
       
   173             buttonPos = LayoutButton( i, buttonPos );
       
   174             }
       
   175         }
       
   176     else
       
   177         {
       
   178         // In landscape, buttons are laid out from right to left.
       
   179         // This is achieved by looping button array backwards and laying
       
   180         // those out from left to right.
       
   181         for ( TInt i = iButtons.Count()-1 ; i >= 0  ; --i )
       
   182             {
       
   183             buttonPos = LayoutButton( i, buttonPos );
       
   184             }
       
   185         }
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // CountComponentControls
       
   190 //
       
   191 // ---------------------------------------------------------------------------
       
   192 //
       
   193 TInt CDialerToolbarContainer::CountComponentControls() const
       
   194     {
       
   195     return iButtons.Count();
       
   196     }
       
   197 
       
   198 // ---------------------------------------------------------------------------
       
   199 // ComponentControl
       
   200 //
       
   201 // ---------------------------------------------------------------------------
       
   202 //
       
   203 CCoeControl* CDialerToolbarContainer::ComponentControl( TInt aIndex ) const
       
   204     {
       
   205     CCoeControl* control = NULL;
       
   206     if ( aIndex >= 0 && aIndex < iButtons.Count() )
       
   207         {
       
   208         control = iButtons[ aIndex ];
       
   209         }
       
   210     return control;
       
   211     }
       
   212 
       
   213 // ---------------------------------------------------------------------------
       
   214 // HandleControlEventL
       
   215 //
       
   216 // ---------------------------------------------------------------------------
       
   217 //
       
   218 void CDialerToolbarContainer::HandleControlEventL( CCoeControl* aControl, TCoeEvent aEventType )
       
   219     {
       
   220     if ( aEventType == MCoeControlObserver::EEventStateChanged )
       
   221         {
       
   222         // Handle button press. 
       
   223 
       
   224         // Multistate buttons change state automatically when pressed. 
       
   225         // Revert this change as we do not want to use states
       
   226         // for "toggle button" type of functionality but to give one button
       
   227         // different functions depending on the situation.
       
   228         UpdateButtonStates();
       
   229 
       
   230         // Handle the command attached to the button
       
   231         CAknButton* button = static_cast<CAknButton*>( aControl );
       
   232         TInt commandId = ButtonCommand( *button );
       
   233         
       
   234         if ( commandId == EPhoneDialerCmdClear )
       
   235             {
       
   236             // simulate backspace
       
   237             TKeyEvent keyEvent;
       
   238             keyEvent.iModifiers = 0;
       
   239             keyEvent.iRepeats = 0;
       
   240             keyEvent.iCode = EKeyBackspace;
       
   241             keyEvent.iScanCode = EStdKeyBackspace;
       
   242             iCoeEnv->SimulateKeyEventL( keyEvent, EEventKey );
       
   243             }
       
   244         else
       
   245             {
       
   246             // Forward pressed toolbar button to the framework 
       
   247             // so that we can handle it in active state
       
   248             CAknAppUi* appUi = static_cast<CAknAppUi*>( iCoeEnv->AppUi() );
       
   249             appUi->ProcessCommandL( commandId );  
       
   250             }
       
   251         }
       
   252     }
       
   253 
       
   254 // ---------------------------------------------------------------------------
       
   255 // HandlePointerEventL
       
   256 //
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 void CDialerToolbarContainer::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   260     {
       
   261     iLatestPointerEvent = aPointerEvent;
       
   262     CCoeControl::HandlePointerEventL( aPointerEvent );
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // HandleGainingForeground
       
   267 //
       
   268 // ---------------------------------------------------------------------------
       
   269 //
       
   270 void CDialerToolbarContainer::HandleGainingForeground()
       
   271     {
       
   272     // no implementation needed
       
   273     }
       
   274     
       
   275 // ---------------------------------------------------------------------------
       
   276 // HandleLosingForeground
       
   277 //
       
   278 // ---------------------------------------------------------------------------
       
   279 //
       
   280 void CDialerToolbarContainer::HandleLosingForeground()
       
   281     {
       
   282     // This is needed when dialer control disappeares during keypress. 
       
   283     // Last pressed pointer event must be forwarted to framework 
       
   284     // as pointer up event. Thus button is set to unpressed state etc. 
       
   285     // 
       
   286     if ( iLatestPointerEvent.iType != TPointerEvent::EButton1Up )
       
   287         {    
       
   288         iLatestPointerEvent.iType = TPointerEvent::EButton1Up;
       
   289         TRAP_IGNORE( HandlePointerEventL( iLatestPointerEvent ) );
       
   290         }    
       
   291     }
       
   292 
       
   293 // ---------------------------------------------------------------------------
       
   294 // CreateButtonsL
       
   295 //
       
   296 // ---------------------------------------------------------------------------
       
   297 //
       
   298 void CDialerToolbarContainer::CreateButtonsL()
       
   299     {
       
   300     // Create the avkon button objects
       
   301     for ( TInt i = 0 ; i < MPhoneDialerController::ENumberOfButtons ; ++i )
       
   302         {
       
   303         CAknButton* button = CAknButton::NewLC();
       
   304         button->SetContainerWindowL( *this ); // this sets also parent and mopParent
       
   305         button->SetObserver( this );
       
   306         button->SetIconScaleMode( EAspectRatioPreserved );
       
   307         AknsUtils::RegisterControlPosition( button );
       
   308         button->ActivateL();
       
   309         iButtons.AppendL( button );
       
   310         CleanupStack::Pop( button );
       
   311         iButtonCommands.AppendL( RArray<TInt>() );
       
   312         }
       
   313 
       
   314     // Backspace button has auto-repeat feature
       
   315     iButtons[MPhoneDialerController::EClearButton]->SetButtonFlags( KAknButtonKeyRepeat );
       
   316     iButtons[MPhoneDialerController::EClearButton]->SetKeyRepeatInterval( 
       
   317         KDialerToolbarButtonKeyRepeatDelay, KDialerToolbarKeyRepeatInterval );
       
   318     
       
   319     // Call button doesn't use default button background but a green one 
       
   320     // (same as used by in-call view for answer button)
       
   321     iButtons[MPhoneDialerController::ECallButton]->SetFrameAndCenterIds( 
       
   322             KAknsIIDQsnFrButtonNormalAnswer, KAknsIIDQsnFrButtonNormalAnswerCenter,
       
   323             KAknsIIDQsnFrButtonPressedAnswer, KAknsIIDQsnFrButtonPressedAnswerCenter, 
       
   324             KAknsIIDQsnFrButtonInactiveAnswer, KAknsIIDQsnFrButtonInactiveAnswerCenter, 
       
   325             KAknsIIDQsnFrButtonPressedAnswer, KAknsIIDQsnFrButtonPressedAnswerCenter, 
       
   326             KAknsIIDQsnFrButtonInactiveAnswer, KAknsIIDQsnFrButtonInactiveAnswerCenter
       
   327             );
       
   328         
       
   329     // Add button states
       
   330     if ( iContentProvider )
       
   331         {
       
   332         for ( TInt i = 0 ; i < MPhoneDialerController::ENumberOfButtons ; ++i )
       
   333             {
       
   334             MPhoneDialerController::TButtonIndex btnIdx =
       
   335                 static_cast< MPhoneDialerController::TButtonIndex >( i );
       
   336             RPointerArray< MPhoneDialerController::CButtonData > states;
       
   337             CleanupClosePushL( states );
       
   338             iContentProvider->GetButtonData( btnIdx, states );
       
   339             for ( TInt j = 0 ; j < states.Count() ; ++j )
       
   340                 {
       
   341                 TRAP_IGNORE( AddButtonStateL( i, *states[j] ) );
       
   342                 delete states[j];
       
   343                 states[j] = NULL;
       
   344                 }
       
   345             CleanupStack::PopAndDestroy( &states );
       
   346             }
       
   347         }
       
   348     }
       
   349 
       
   350 // ---------------------------------------------------------------------------
       
   351 // DeleteButtons
       
   352 // Reset internal arrays holding the button data
       
   353 // ---------------------------------------------------------------------------
       
   354 //
       
   355 void CDialerToolbarContainer::DeleteButtons()
       
   356     {
       
   357     for ( TInt i = 0 ; i < iButtons.Count() ; ++i )
       
   358         {
       
   359         AknsUtils::DeregisterControlPosition( iButtons[i] );
       
   360         }
       
   361     iButtons.ResetAndDestroy();
       
   362     
       
   363     for ( TInt i = 0 ; i < iButtonCommands.Count() ; ++i )
       
   364         {
       
   365         iButtonCommands[i].Reset();
       
   366         }
       
   367     iButtonCommands.Reset();
       
   368     }
       
   369 
       
   370 // ---------------------------------------------------------------------------
       
   371 // AddButtonStateL
       
   372 //
       
   373 // ---------------------------------------------------------------------------
       
   374 //
       
   375 void CDialerToolbarContainer::AddButtonStateL( TInt aButtonIndex, 
       
   376         MPhoneDialerController::CButtonData& aButtonData )
       
   377     {
       
   378     iButtons[ aButtonIndex ]->AddStateL(
       
   379             aButtonData.iIcon,      //CGulIcon* aIcon, 
       
   380             NULL,                   //CGulIcon* aDimmedIcon, 
       
   381             NULL,                   //CGulIcon* aPressedIcon,
       
   382             NULL,                   //CGulIcon* aHoverIcon,
       
   383             KNullDesC,              //const TDesC& aText, 
       
   384             *aButtonData.iTooltip,  //const TDesC& aHelpText, 
       
   385             0 );                    //const TInt aStateFlags
       
   386     aButtonData.iIcon = NULL; // ownership transferred
       
   387     iButtonCommands[ aButtonIndex ].AppendL( aButtonData.iCommandId );
       
   388     }
       
   389 
       
   390 // ---------------------------------------------------------------------------
       
   391 // ButtonCommand
       
   392 //
       
   393 // ---------------------------------------------------------------------------
       
   394 //
       
   395 TInt CDialerToolbarContainer::ButtonCommand( const CAknButton& aButton ) const
       
   396     {
       
   397     TInt commandId = KErrNotFound;
       
   398     
       
   399     // Find out index of the button in iButtons array
       
   400     TInt btnIndex = KErrNotFound;
       
   401     for ( TInt i = 0 ; i < iButtons.Count() ; ++i )
       
   402         {
       
   403         if ( iButtons[i] == &aButton )
       
   404             {
       
   405             btnIndex = i;
       
   406             i = iButtons.Count(); // to break out of the loop
       
   407             }
       
   408         }
       
   409     __ASSERT_DEBUG( btnIndex >= 0, DialerPanic( EDialerPanicToolbarButtonNotFound ) );
       
   410     
       
   411     // Find the corresponding command from command array
       
   412     TInt btnStateIdx = aButton.StateIndex();
       
   413     if ( btnIndex < iButtonCommands.Count() &&
       
   414          btnStateIdx < iButtonCommands[btnIndex].Count() )
       
   415         {
       
   416         commandId = iButtonCommands[btnIndex][btnStateIdx];
       
   417         }
       
   418     
       
   419     __ASSERT_DEBUG( commandId != KErrNotFound, DialerPanic( EDialerPanicToolbarButtonNotFound ) );
       
   420     return commandId;
       
   421     }
       
   422 
       
   423 // ---------------------------------------------------------------------------
       
   424 // LayoutButton
       
   425 // Set layout for one button.
       
   426 // ---------------------------------------------------------------------------
       
   427 //
       
   428 TPoint CDialerToolbarContainer::LayoutButton( TInt aButtonIdx, TPoint aPos )
       
   429     {
       
   430     TRect parentRect = Rect();
       
   431 
       
   432     TAknWindowComponentLayout buttonLayout = 
       
   433         ( aButtonIdx == MPhoneDialerController::ECallButton ? 
       
   434           AknLayoutScalable_Apps::cell_dia3_key1_fun_pane( iVariety ) :
       
   435           AknLayoutScalable_Apps::cell_dia3_key0_fun_pane( iVariety ) );
       
   436         
       
   437     TAknLayoutRect layoutRect;
       
   438     layoutRect.LayoutRect( parentRect, buttonLayout );
       
   439     TRect outerRect = layoutRect.Rect();
       
   440     outerRect.SetRect( aPos, outerRect.Size() );
       
   441 
       
   442     TRect innerRect = outerRect;
       
   443     innerRect.Shrink( 1, 1 );
       
   444     iButtons[ aButtonIdx ]->SetRect( innerRect );
       
   445     AknsUtils::RegisterControlPosition( iButtons[ aButtonIdx ] );
       
   446     
       
   447     // Calculate position for the next button
       
   448     TPoint nextPos = aPos;
       
   449     if ( iVariety == EDialerVarietyPortrait )
       
   450         {
       
   451         nextPos.iY += outerRect.Height();
       
   452         }
       
   453     else
       
   454         {
       
   455         nextPos.iX += outerRect.Width();
       
   456         }
       
   457     
       
   458     return nextPos;
       
   459     }
       
   460 
       
   461 // end of file