phoneuis/easydialing/src/easydialinglistbox.cpp
branchRCL_3
changeset 3 8871b09be73b
child 5 2a26698d78ba
equal deleted inserted replaced
2:c84cf270c54f 3:8871b09be73b
       
     1 /*
       
     2 * Copyright (c) 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:  Easy dialing list box.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include "easydialinglistbox.h"
       
    22 #include "easydialinglistboxview.h"
       
    23 #include "easydialinglistboxitemdrawer.h"
       
    24 #include "easydialinglistboxdata.h"
       
    25 #include "easydialingpanics.h"
       
    26 #include "easydialingcontactdatamanager.h"
       
    27 #include "easydialingcrkeys.h"
       
    28 
       
    29 #include <easydialingpluginresources.rsg>
       
    30 
       
    31 #include <phoneappcommands.hrh>
       
    32 #include <phonebook2.mbg>
       
    33 #include <phonebook2ece.mbg>
       
    34 
       
    35 #include <ccappcommlauncherpluginrsc.rsg>
       
    36 
       
    37 // AvKON and drawing header files
       
    38 
       
    39 #include <aknpointereventsuppressor.h> 
       
    40 #include <aknlongtapdetector.h> // Required for touch
       
    41 #include <AknsFrameBackgroundControlContext.h>
       
    42 #include <AknInfoPopupNoteController.h>  // tooltips
       
    43 
       
    44 #include <aknlayoutscalable_apps.cdl.h>
       
    45 #include <layoutmetadata.cdl.h>
       
    46 #include <gulicon.h>
       
    47 #include <centralrepository.h>
       
    48 #include <bautils.h>    // for BaflUtils
       
    49 
       
    50 #include <aknlistloadertfx.h>
       
    51 #include <aknlistboxtfxinternal.h>
       
    52 #include <aknlistboxtfx.h>
       
    53 
       
    54 // EXTERNAL DATA STRUCTURES
       
    55 
       
    56 // EXTERNAL FUNCTION PROTOTYPES  
       
    57 
       
    58 extern TRect ContactImageBoundingBox( const TRect& aItemRect );
       
    59 extern TRect ActionMenuIconBoundingBox(const TRect& aItemRect);
       
    60 
       
    61 // CONSTANTS
       
    62 static const TInt KListBoxMarginWidth = 2;
       
    63 static const TInt KMaxVisibleItemsPortrait = 3;
       
    64 static const TInt KMaxVisibleItemsLandscape = 2;
       
    65 
       
    66 // MACROS
       
    67 
       
    68 // LOCAL CONSTANTS AND MACROS
       
    69 
       
    70 // MODULE DATA STRUCTURES
       
    71 
       
    72 // LOCAL FUNCTION PROTOTYPES
       
    73 
       
    74 // FORWARD DECLARATIONS
       
    75 
       
    76 
       
    77 /*
       
    78  * ==============================================================================
       
    79  * 
       
    80  * 
       
    81  * class CEasyDialingListBox
       
    82  * 
       
    83  * 
       
    84  * ==============================================================================
       
    85  */
       
    86 
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // CEasyDialingListBox
       
    90 // 
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 CEasyDialingListBox::CEasyDialingListBox() :
       
    94     CEikFormattedCellListBox()
       
    95     {
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // ~CEasyDialingListBox
       
   100 // 
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 CEasyDialingListBox::~CEasyDialingListBox()
       
   104     {
       
   105     delete iBGContext;    
       
   106     delete iLongTapDetector;
       
   107     }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // ConstructL
       
   111 // 
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 void CEasyDialingListBox::ConstructL( TInt aFlags, 
       
   115         CEasyDialingContactDataManager* aContactDataManager )
       
   116     {
       
   117     CEikFormattedCellListBox::ConstructL( NULL, aFlags );
       
   118     
       
   119     iLongTapDetector = CAknLongTapDetector::NewL( this );
       
   120  
       
   121     CEasyDialingListBoxItemDrawer* drawer = static_cast<CEasyDialingListBoxItemDrawer*> (iItemDrawer);
       
   122     CEasyDialingListBoxData* data = drawer->EasyDialingCellData();
       
   123     data->SetContactDataManager(aContactDataManager);
       
   124     data->SetEDLBXControl(this);
       
   125     
       
   126     iBGContext = CAknsFrameBackgroundControlContext::NewL( KAknsIIDQsnFrPopupSub,
       
   127             Rect(), Rect(), EFalse );
       
   128        
       
   129     // ContactDataManager is accessed from SizeChanged. If list item size
       
   130     // changes -> thumbnail size changes
       
   131     iContactDataManager = aContactDataManager;
       
   132     
       
   133     drawer->SetColors();
       
   134 
       
   135     CreateScrollBarFrameL( ETrue );
       
   136     ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
       
   137     }
       
   138 
       
   139 
       
   140 // -----------------------------------------------------------------------------
       
   141 // MakeViewClassInstanceL
       
   142 // 
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 CListBoxView* CEasyDialingListBox::MakeViewClassInstanceL()
       
   146     {
       
   147     return (new ( ELeave ) CEasyDialingListBoxView);
       
   148     }
       
   149 
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // ItemDrawer
       
   153 // 
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 CEasyDialingListBoxItemDrawer* CEasyDialingListBox::ItemDrawer() const
       
   157     {
       
   158     return (CEasyDialingListBoxItemDrawer*) iItemDrawer;
       
   159     }
       
   160 
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // FocusChanged
       
   164 // 
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 void CEasyDialingListBox::FocusChanged( TDrawNow aDrawNow )
       
   168     {
       
   169     if ( !IsFocused() )
       
   170         {
       
   171         CEasyDialingListBoxView* view = static_cast<CEasyDialingListBoxView*>( iView );
       
   172         view->SetCurrentItemIndexToNone();
       
   173         
       
   174         // Invalidate window area. 
       
   175         // This fixes the drawing problem that the top 
       
   176         // of listbox is not always redrawn on the area that overlaps 
       
   177         // the status pane area. 
       
   178         // TODO: This overlapping no longer happens in 9.2 so this may
       
   179         // now be unnecessary.
       
   180         Window().Invalidate();
       
   181         }
       
   182     CEikFormattedCellListBox::FocusChanged( aDrawNow );
       
   183     }
       
   184 
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // CreateItemDrawerL
       
   188 // 
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 void CEasyDialingListBox::CreateItemDrawerL()
       
   192     {
       
   193     CEasyDialingListBoxData* celldata = CEasyDialingListBoxData::NewL();
       
   194     CleanupStack::PushL( celldata );
       
   195     iItemDrawer = new(ELeave) CEasyDialingListBoxItemDrawer(Model(), iEikonEnv->NormalFont(), celldata);
       
   196     CleanupStack::Pop( celldata );  
       
   197     }
       
   198 
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // Draw
       
   202 // 
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 void CEasyDialingListBox::Draw(const TRect& aRect) const
       
   206     {
       
   207     MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iItemDrawer->Gc() );
       
   208     if ( transApi )
       
   209         {
       
   210         transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeMainPane );
       
   211         transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, this->Rect() );
       
   212         }
       
   213     
       
   214     if (!iView->RedrawDisabled() )
       
   215         {
       
   216         TRect clientRect( Rect() );
       
   217         TRect viewRect = iView->ViewRect();
       
   218         
       
   219         if ( transApi )
       
   220             {
       
   221             transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   222             }
       
   223 
       
   224         AknsDrawUtils::BackgroundBetweenRects( 
       
   225             AknsUtils::SkinInstance(), 
       
   226             iBGContext, 
       
   227             this, 
       
   228             *iItemDrawer->Gc(), 
       
   229             clientRect, 
       
   230             viewRect );
       
   231         
       
   232         if ( transApi )
       
   233             {
       
   234             transApi->StopDrawing();
       
   235             }
       
   236         }
       
   237     
       
   238     if ( iModel->NumberOfItems() )
       
   239         {
       
   240         // Draw the actual list
       
   241         iView->Draw(&aRect);
       
   242         }
       
   243     if ( transApi )
       
   244         {
       
   245         transApi->EndViewRedraw( aRect );
       
   246         }
       
   247     }
       
   248 
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // HandleResourceChange
       
   252 // 
       
   253 // -----------------------------------------------------------------------------
       
   254 //
       
   255 void CEasyDialingListBox::HandleResourceChange(TInt aType)
       
   256     {
       
   257     CEikFormattedCellListBox::HandleResourceChange( aType );
       
   258     iSBFrame->VerticalScrollBar()->HandleResourceChange( aType );
       
   259     iSBFrame->DrawScrollBarsNow();
       
   260     ItemDrawer()->SetColors();
       
   261     
       
   262     // Base call to HandleResourceChange justifies the list to even items
       
   263     // on the top. This causes problems when listbox height is not a multiple of
       
   264     // listitem heights. Fix scrolling manually for these cases.
       
   265     TRAP_IGNORE( HandleItemAdditionL() ); // needed to prevent drawing problems
       
   266     TInt scrollIndex = ( IsFocused() ? CurrentItemIndex() : iNumberOfNames - 1 );
       
   267     ScrollToMakeItemVisible( scrollIndex );
       
   268     
       
   269     DrawDeferred();
       
   270     }
       
   271 
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // SizeChanged
       
   275 // 
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 void CEasyDialingListBox::SizeChanged()
       
   279     {
       
   280     CEikFormattedCellListBox::SizeChanged();
       
   281     
       
   282     // Set the listbox colors.
       
   283     // For some reason, calling this in HandleResourceChange is not enough, it does
       
   284     // not get called in situation it should.
       
   285     ItemDrawer()->SetColors();
       
   286    
       
   287     // resize scroll bar
       
   288     if ( iSBFrame )
       
   289         {
       
   290         TAknLayoutRect rect;
       
   291         TInt variety = ( Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0 );
       
   292     
       
   293         TAknWindowComponentLayout viewLayout( AknLayoutScalable_Apps::dia3_list_pane( variety ) );
       
   294         rect.LayoutRect( Rect(), viewLayout );
       
   295         TRect viewRect( rect.Rect() );
       
   296         // Add a bit of margin around the view as layout doesn't define any
       
   297         viewRect.Shrink( KListBoxMarginWidth, KListBoxMarginWidth );
       
   298         
       
   299         TAknWindowComponentLayout scrollBarLayout( AknLayoutScalable_Apps::scroll_pane_cp12() );
       
   300         rect.LayoutRect( Rect(), scrollBarLayout );
       
   301         TRect scrollBarRect( rect.Rect() );
       
   302 
       
   303         iView->SetViewRect( viewRect );
       
   304         
       
   305         CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*>( iSBFrame->VerticalScrollBar() );
       
   306 
       
   307         scrollbar->SetFixedLayoutRect( scrollBarRect );
       
   308         scrollbar->SetRect( scrollBarRect );
       
   309         
       
   310         TRect viewAndScrollBarRect( viewRect );
       
   311         
       
   312         if ( AknLayoutUtils::LayoutMirrored() )
       
   313             {
       
   314             viewAndScrollBarRect.iTl = scrollBarRect.iTl;
       
   315             }
       
   316         else
       
   317             {
       
   318             viewAndScrollBarRect.iBr = scrollBarRect.iBr;
       
   319             }
       
   320         iBGContext->SetFrameRects( Rect(), viewAndScrollBarRect );
       
   321         }
       
   322     }
       
   323 
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // MopSupplyObject
       
   327 // 
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 TTypeUid::Ptr CEasyDialingListBox::MopSupplyObject( TTypeUid aId )
       
   331     {
       
   332     if ( aId.iUid == MAknsControlContext::ETypeId && iBGContext )
       
   333         {
       
   334         return MAknsControlContext::SupplyMopObject( aId, iBGContext );
       
   335         }
       
   336     return CEikFormattedCellListBox::MopSupplyObject( aId );    
       
   337     }
       
   338 
       
   339 // -----------------------------------------------------------------------------
       
   340 // MakeVisible
       
   341 // 
       
   342 // -----------------------------------------------------------------------------
       
   343 //
       
   344 void CEasyDialingListBox::MakeVisible( TBool aVisible )
       
   345     {
       
   346     if ( aVisible != IsVisible() )
       
   347         {
       
   348         CEikFormattedCellListBox::MakeVisible( aVisible );
       
   349         if ( iSBFrame )
       
   350             {
       
   351             CEikScrollBar* sb = iSBFrame->GetScrollBarHandle( CEikScrollBar::EVertical );
       
   352             if ( sb )
       
   353                 {
       
   354                 sb->MakeVisible( aVisible );
       
   355                 if ( aVisible )
       
   356                     {
       
   357                     UpdateScrollBarThumbs();
       
   358                     }
       
   359                 }
       
   360             }
       
   361         }
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // SetMaxRect
       
   366 //
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 void CEasyDialingListBox::SetMaxRect( TRect aMaxRect )
       
   370     {
       
   371     iMaxRect = aMaxRect;
       
   372 
       
   373     // Update the list item size according the maximum view rect size
       
   374     TInt variety = ( Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0 );
       
   375     TAknLayoutRect maxViewLayout;
       
   376     maxViewLayout.LayoutRect( aMaxRect, AknLayoutScalable_Apps::dia3_list_pane( variety ) );
       
   377     TRect maxViewRect( maxViewLayout.Rect() );
       
   378     maxViewRect.Shrink( KListBoxMarginWidth, KListBoxMarginWidth ); // layout data doens't include any margins but we have added some
       
   379     
       
   380     TInt maxItemsShown = ( variety ? KMaxVisibleItemsLandscape : KMaxVisibleItemsPortrait );
       
   381     TInt itemHeight = maxViewRect.Height() / maxItemsShown;
       
   382     TRAP_IGNORE( SetItemHeightL( itemHeight ) );
       
   383 
       
   384     // Calculate new thumbnail rect from item size
       
   385     TSize itemSize( maxViewRect.Width(), itemHeight );
       
   386     TRect thumbnailRect = ContactImageBoundingBox( itemSize );
       
   387     iContactDataManager->SetThumbnailSize( thumbnailRect.Size() ); // reloads thumbnails if the new size is different from old one
       
   388 
       
   389     // Inform listbox data class about changed list item size
       
   390     ItemDrawer()->EasyDialingCellData()->HandleItemSizeChange();
       
   391     }
       
   392 
       
   393 // -----------------------------------------------------------------------------
       
   394 // SetRectToNumberOfItems
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 void CEasyDialingListBox::SetRectToNumberOfItems( TInt aNumberOfNames ) 
       
   398     {
       
   399     iNumberOfNames = aNumberOfNames;
       
   400 
       
   401     TRect listboxRect( iMaxRect );
       
   402     
       
   403     // Make listbox smaller if maximum size is not needed to show
       
   404     // all list items.
       
   405     TInt requiredHeight = GetHeightBasedOnNumberOfItems( iNumberOfNames );
       
   406     if ( requiredHeight < listboxRect.Height() )
       
   407         {
       
   408         // Shrink rect height so that bottom of the rect doesn't move
       
   409         listboxRect.iTl.iY += ( listboxRect.Height() - requiredHeight );
       
   410         }
       
   411     
       
   412     SetRect( listboxRect );
       
   413     }
       
   414 
       
   415 
       
   416 
       
   417 // -----------------------------------------------------------------------------
       
   418 // SetFocusedWithKeyEventL
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 TKeyResponse CEasyDialingListBox::SetFocusedWithKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
       
   422     {
       
   423     TKeyResponse keyResponse = EKeyWasNotConsumed;
       
   424     TInt keyCode = aKeyEvent.iCode;
       
   425             
       
   426     // Disable redrawing temporarily.
       
   427     // This is because OfferKeyEventL puts the focus to the wrong item,
       
   428     // and we don't want to show it flashing there.
       
   429     // Make sure that no leave happens before redraw is enabled again.
       
   430     iView->SetDisableRedraw( ETrue );
       
   431         
       
   432     TRAP_IGNORE( keyResponse = OfferKeyEventL( aKeyEvent, aType ) );
       
   433     
       
   434     TInt itemToFocus = ( keyCode == EKeyUpArrow ? iNumberOfNames - 1 : 0 );
       
   435     ScrollToMakeItemVisible( itemToFocus );
       
   436     SetCurrentItemIndex( itemToFocus );
       
   437         
       
   438     iView->SetDisableRedraw( EFalse );
       
   439     
       
   440     DrawDeferred();
       
   441     
       
   442     return keyResponse;
       
   443     }
       
   444 
       
   445 
       
   446 // -----------------------------------------------------------------------------
       
   447 // GetHeightBasedOnNumberOfItems
       
   448 // 
       
   449 // -----------------------------------------------------------------------------
       
   450 //
       
   451 TInt CEasyDialingListBox::GetHeightBasedOnNumberOfItems( TInt aNum ) const
       
   452     {
       
   453     return ( ItemHeight()*aNum + KListBoxMarginWidth*2 ); 
       
   454     }
       
   455 
       
   456 
       
   457 // -----------------------------------------------------------------------------
       
   458 // CurrentContactDataIndex
       
   459 // 
       
   460 // -----------------------------------------------------------------------------
       
   461 //
       
   462 TInt CEasyDialingListBox::CurrentContactDataIndex()
       
   463     {
       
   464     if ( CurrentItemIndex() >= 0 ) 
       
   465         {
       
   466         TPtrC itemText = Model()->ItemText( CurrentItemIndex() );
       
   467         TPtrC indexText;
       
   468         
       
   469         TInt error = TextUtils::ColumnText( indexText , 0, &itemText );
       
   470         __ASSERT_DEBUG( error == KErrNone, EasyDialingPanic( EEasyDialingPanicInvalidListBoxModelString ) );
       
   471 
       
   472         TUint id( 0 );
       
   473         TLex lex( indexText );
       
   474         error = lex.Val( id, EHex );
       
   475         __ASSERT_DEBUG( error == KErrNone, EasyDialingPanic( EEasyDialingPanicInvalidListBoxModelString ) );
       
   476         
       
   477         return id;
       
   478         }
       
   479     else 
       
   480         {
       
   481         return KErrNotFound;
       
   482         }
       
   483     }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // CurrentContactLinkLC
       
   487 // 
       
   488 // -----------------------------------------------------------------------------
       
   489 //
       
   490 HBufC8* CEasyDialingListBox::CurrentContactLinkLC()
       
   491     {
       
   492     TInt index = CurrentContactDataIndex();
       
   493     return iContactDataManager->ContactLinkLC( index );
       
   494     }
       
   495 
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 // HandleLongTapEventL
       
   499 // Callback from CAknLongTapDetector.
       
   500 // -----------------------------------------------------------------------------
       
   501 //
       
   502 void CEasyDialingListBox::HandleLongTapEventL( const TPoint& /*aPenEventLocation*/, 
       
   503                                                const TPoint& /*aPenEventScreenLocation*/ )
       
   504     {
       
   505     ReportListBoxEventL( static_cast<MEikListBoxObserver::TListBoxEvent>
       
   506             ( KEasyDialingContactLongTapped ) );
       
   507     iPointerLongPressHandled = ETrue;
       
   508     }
       
   509 
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // HandlePointerEventL
       
   513 // Pointer event handling within the EasyDialingListBox.
       
   514 // -----------------------------------------------------------------------------
       
   515 //
       
   516 void CEasyDialingListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   517     {
       
   518     // Button down event starts new pointer press. Reset flags at this point.
       
   519     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   520         {
       
   521         iPointerLongPressHandled = EFalse;
       
   522         }
       
   523     
       
   524     iLongTapDetector->PointerEventL(aPointerEvent);
       
   525     if ( iPointerLongPressHandled )
       
   526         {
       
   527         // No further handling is made after long tap on list item
       
   528         // has been detected.
       
   529         return;
       
   530         }
       
   531 
       
   532     CEikFormattedCellListBox::HandlePointerEventL( aPointerEvent );
       
   533     }
       
   534 
       
   535 
       
   536 // end of file
       
   537