calendarui/views/src/calendaylistboxview.cpp
changeset 0 f979ecb2b13e
child 13 0f07cd1b5772
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/calendarui/views/src/calendaylistboxview.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,532 @@
+/*
+* Copyright (c) 2002 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:   ListBox View class. The class has a special drawing and
+ *                special cusor moving.
+ *
+*/
+
+
+
+//debug
+#include "calendarui_debug.h"
+
+
+// INCLUDE FILES
+#include "calendaylistboxview.h"
+#include "CalendarVariant.hrh"
+#include "calendrawutils.h"
+
+#include <AknUtils.h>
+#include <AknsDrawUtils.h>
+#include <AknsEffectAnim.h>
+#include <eikfrlbd.h>
+
+#include <aknlayoutscalable_apps.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+
+const TInt KMaxLineInACell(4);
+
+#define ITEM_EXISTS_ONCE(x) (((x) > -1) && ((x) < iModel->NumberOfItems()))
+
+// ================= MEMBER FUNCTIONS =======================
+
+CCalenDayListBoxView::CCalenDayListBoxView(CCoeControl* aParent)
+    : iParent(aParent)
+    {
+    TRACE_ENTRY_POINT;
+    TRACE_EXIT_POINT;
+    }
+
+CCalenDayListBoxView::~CCalenDayListBoxView()
+    {
+    TRACE_ENTRY_POINT;
+    
+    delete iCellArray;
+    
+    TRACE_EXIT_POINT;
+    }
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::SetCellArray
+// Sets a array for dividing a cell
+// (other items were commented in a header).
+// ----------------------------------------------------
+//
+void CCalenDayListBoxView::SetCellArray(CArrayFix<TInt>* aArray)
+    {
+    TRACE_ENTRY_POINT;
+    
+    delete iCellArray;
+    iCellArray = aArray;
+    
+    TRACE_EXIT_POINT;
+    }
+
+TInt CCalenDayListBoxView::FirstLineOfCell(TInt aLine) const
+    {
+    TRACE_ENTRY_POINT;
+    
+    for (TInt i = aLine; i >= 0; i--)
+        {
+        if (IsFirstLineOfCell(i))
+            {
+            return i;
+            }
+        }
+    
+    TRACE_EXIT_POINT;
+    return aLine; // FIXME, should not get here. 
+    }
+
+TInt CCalenDayListBoxView::LastLineOfCell(TInt aLine) const
+    {
+    TRACE_ENTRY_POINT;
+    
+    for (TInt i = aLine; i < iModel->NumberOfItems(); ++i)
+        {
+        if (IsLastLineOfCell(i))
+            {
+            return i;
+            }
+        }
+    
+    TRACE_EXIT_POINT;
+    return aLine; // FIXME, should not get here
+    }
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::IsLastLineOfCell
+//
+// (other items were commented in a header).
+// ----------------------------------------------------
+//
+TBool CCalenDayListBoxView::IsLastLineOfCell(TInt aLine) const
+    {
+    TRACE_ENTRY_POINT;
+    
+    TKeyArrayFix key(0, ECmpTInt32);
+    TInt index(0);
+    TBool retValue(EFalse);
+    if (iCellArray->FindIsq(aLine, key, index) == 0)
+        {
+        retValue = ETrue;
+        }
+    
+    TRACE_EXIT_POINT;
+    return retValue;
+    }
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::IsFirstLineOfCell
+//
+// (other items were commented in a header).
+// ----------------------------------------------------
+//
+TBool CCalenDayListBoxView::IsFirstLineOfCell(TInt aLine) const
+    {
+    TRACE_ENTRY_POINT;
+    
+    TKeyArrayFix key(0, ECmpTInt32);
+    TInt index(0);
+    TBool retValue(EFalse);
+    if (aLine == 0)
+        {
+        retValue = ETrue;
+        }
+    else if (iCellArray->FindIsq(aLine -1, key, index) == 0)
+        {
+        retValue = ETrue;            
+        }
+
+    TRACE_EXIT_POINT;
+    return retValue;
+    }
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::DrawCell
+//
+// (other items were commented in a header).
+// ----------------------------------------------------
+//
+void CCalenDayListBoxView::DrawCell(TInt aIndex)
+    {
+    TRACE_ENTRY_POINT;
+    
+    TInt lastLine(LastLineOfCell(aIndex));
+    for (TInt i(aIndex); i <= lastLine; ++i)
+        {
+        DrawItem(i);
+        }
+    
+    TRACE_EXIT_POINT;
+    }
+
+// ----------------------------------------------------
+// 
+// ----------------------------------------------------
+//
+TRect CCalenDayListBoxView::DayViewItemRect(TInt aItemIndex) const
+    {
+    TRACE_ENTRY_POINT;
+
+    TInt topLine(FirstLineOfCell(aItemIndex));
+    TInt bottomLine(LastLineOfCell(aItemIndex));
+
+    //topLine = topLine > iTopItemIndex ? topLine : iTopItemIndex;
+
+    bottomLine = bottomLine > iBottomItemIndex ? iBottomItemIndex : bottomLine;
+    TRect rectHighlight(ItemPos(topLine), ItemPos(bottomLine));
+    rectHighlight.iBr += CListBoxView::ItemSize(bottomLine);
+    
+    TRACE_EXIT_POINT;
+    return rectHighlight;
+    }
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::ItemSize
+//
+// (other items were commented in a header).
+// ----------------------------------------------------
+//    
+TSize CCalenDayListBoxView::ItemSize(TInt aItemIndex) const
+    {
+    TRACE_ENTRY_POINT;
+    TRACE_EXIT_POINT;
+    return DayViewItemRect(aItemIndex).Size();
+    }
+
+void CCalenDayListBoxView::DrawItem(TInt aItemIndex) const
+    {
+    TRACE_ENTRY_POINT;
+    
+    PIM_TRAPD_HANDLE(DrawItemL(aItemIndex));
+    
+    TRACE_ENTRY_POINT;
+    }
+
+void CCalenDayListBoxView::DrawItemL(TInt aItemIndex) const
+    {
+    TRACE_ENTRY_POINT;
+
+    // FIXME: this function needs cleanup. 
+    if(RedrawDisabled() || !IsVisible())
+        {
+        return;
+        }
+
+    if((ITEM_EXISTS_ONCE(aItemIndex)) && ItemIsVisible(aItemIndex))
+        {
+        TBool highlight(EFalse);
+        if(aItemIndex >= iCurrentItemIndex && aItemIndex < iCurrentItemIndex + KMaxLineInACell)
+            {
+            TInt nextCell(LastLineOfCell(iCurrentItemIndex) + 1);
+
+        if ( !( iItemDrawer->Flags()
+                & CTextListItemDrawer::EDisableHighlight )
+                && aItemIndex < nextCell )
+            {
+            highlight = ETrue;
+            }
+            }
+        TBool hlDone( EFalse );
+        TBool animHLDone( EFalse );
+
+        MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+        CFormattedCellListBoxData* data = static_cast<CFormattedCellListBoxItemDrawer*>(iItemDrawer)->FormattedCellData();
+
+        // Skinned highlight
+        if( ( highlight && IsFirstLineOfCell( aItemIndex ) ) ||(highlight && aItemIndex == iTopItemIndex))
+            {
+            MAknsControlContext *cc = AknsDrawUtils::ControlContext( iParent );
+
+            if(!cc)
+                {
+                cc = static_cast<CFormattedCellListBoxItemDrawer*>(iItemDrawer)->FormattedCellData()->SkinBackgroundContext();
+                }
+
+            TRect dayViewItemRect( DayViewItemRect( aItemIndex ) );
+            TAknLayoutRect list_highlight_pane_cp1;
+            list_highlight_pane_cp1.LayoutRect( dayViewItemRect, AknLayoutScalable_Avkon::list_highlight_pane_cp1().LayoutLine() );
+
+            if( data->HighlightAnim() && data )
+                {
+                data->SetItemCellSize( dayViewItemRect.Size() ); // ??? 
+                data->AboutToDrawHighlightAnim();
+                if( data->HighlightAnim() )
+                    hlDone = data->HighlightAnim()->Render( *iGc, list_highlight_pane_cp1.Rect() );
+                animHLDone = hlDone;
+                }
+
+            // Either animation does not exist or drawing it failed
+            if( !hlDone )
+                {
+                if( cc )
+                    {
+                    AknsDrawUtils::Background( skin, cc, iParent, *iGc, dayViewItemRect); //??? Isn't it this drawn already?
+                    }
+
+                iGc->SetPenStyle(CGraphicsContext::ENullPen);
+
+                // Skin Center layout 
+                TAknLayoutRect list_highlight_pane_g1_cp1;
+                list_highlight_pane_g1_cp1.LayoutRect( list_highlight_pane_cp1.Rect(), AknLayoutScalable_Avkon::list_highlight_pane_g1_cp1().LayoutLine() );
+
+                hlDone = AknsDrawUtils::DrawFrame(skin, *iGc, 
+                                                  list_highlight_pane_cp1.Rect(), // whole highlight rect
+                                                  list_highlight_pane_g1_cp1.Rect(), // skin center rect
+                                                  KAknsIIDQsnFrList, KAknsIIDQsnFrListCenter);
+                }
+            }
+
+        TBool skinFlg(data->SkinEnabled());
+
+        iGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
+
+        // FIXME: investigate if this is really needed
+        if(highlight)
+            {
+            //iGc->SetDrawMode( CGraphicsContext::EDrawModeAND );
+            data->SetSkinEnabledL( EFalse );
+            }
+        TRect rect( ItemPos( aItemIndex ), CListBoxView::ItemSize( aItemIndex ) );
+
+        // Non-highlighted cell skin background
+        if(!highlight && iParent)
+            {
+            MAknsControlContext *cc = AknsDrawUtils::ControlContext(iParent);
+            if(!cc)
+                {
+                cc = static_cast<CFormattedCellListBoxItemDrawer*>(iItemDrawer)->FormattedCellData()->SkinBackgroundContext();
+                }
+
+            if(cc)
+                {
+                AknsDrawUtils::Background( skin, cc, iParent, *iGc, rect);
+                }
+            }
+
+        // Text and graphic content 
+        iItemDrawer->DrawItem(aItemIndex, ItemPos(aItemIndex), ItemIsSelected(aItemIndex), highlight, 0, 0 );
+
+        // if the highlight is animated we need to redraw all lines of a multi-line item
+        if( animHLDone )
+            {
+            TInt index( aItemIndex );
+            while( !IsLastLineOfCell( index ) )
+                {
+                if( ItemIsVisible( ++index ) )
+                    {
+                    iItemDrawer->DrawItem( index, ItemPos( index ), ItemIsSelected( index ), highlight, 0, 0 );
+                    }
+                }
+            }
+
+        iGc->SetDrawMode( CGraphicsContext::EDrawModePEN );
+        data->SetSkinEnabledL( skinFlg );
+
+        // Line between cells
+        if( IsLastLineOfCell(aItemIndex) && !highlight )
+            {
+            // Get line color 
+            TRgb lineColor(0,0,0);
+            AknsUtils::GetCachedColor(AknsUtils::SkinInstance(), lineColor,
+                                      KAknsIIDQsnLineColors,
+                                      EAknsCIQsnLineColorsCG2);
+            iGc->SetPenColor( lineColor );
+            iGc->SetBrushColor( lineColor );
+            iGc->SetPenStyle(CGraphicsContext::ESolidPen);
+            iGc->SetBrushStyle(CGraphicsContext::ENullBrush);
+
+            // Draw line. There is graphic item qgn_graf_line_cale_day defined for line, but using it would require
+            // caching it first. To be done later? 
+    #ifndef RD_CALEN_MIDNIGHT_VISUALIZATION
+            TInt variety_g2 = 0; // We don't care about variety, because separator line definition is same for all  
+    #else
+            TInt variety_g2(-1);    
+            TInt countryCode( User::Language() );
+            TLocale locale;
+            locale.Refresh();
+            TTimeFormat timeFormat( locale.TimeFormat() );
+
+            if( timeFormat == ETime24 )
+                {
+                // Option 1: 24 hour        
+                variety_g2 = 0;
+                }
+            // 12 hour
+            else if( countryCode == ELangCzech )
+                {
+                // Option 3: Czech, 12 hour with Arrow
+                variety_g2 = 8;
+                }
+            else
+                {
+                // Option 15: 12 hour, with Arrow
+                variety_g2 = 7;
+                }
+
+     #endif // RD_CALEN_MIDNIGHT_VISUALIZATION 
+                     
+            TAknLayoutRect list_cale_time_pane_g2;
+            list_cale_time_pane_g2.LayoutRect( rect, AknLayoutScalable_Apps::list_cale_time_pane_g2( variety_g2 ).LayoutLine() );
+            iGc->DrawRect( list_cale_time_pane_g2.Rect() );
+            }
+        }
+    
+    TRACE_EXIT_POINT;
+    }
+
+// ----------------------------------------------------
+// 
+// ----------------------------------------------------
+//
+void CCalenDayListBoxView::ScrollToItemL(TInt aItemIndex, TSelectionMode aSelectionMode)
+    {
+    TRACE_ENTRY_POINT;
+    
+    TInt oldItemIndex = iCurrentItemIndex;
+    TInt oldTopIndex = iTopItemIndex;
+
+    // To prevent incorrect drawing and flickering, we just move focus
+    // without updating the screen. Uikon list can't draw correct multirow 
+    // focus for us
+    // Updating is done below. 
+    VerticalMoveToItemL(aItemIndex, aSelectionMode);
+
+    //These two scrolls ensure that all lines of item are visible.
+    //If list is scrolled, it is correctly updated and drawn by these methods
+    ScrollToMakeItemVisible( FirstLineOfCell(aItemIndex) );
+    ScrollToMakeItemVisible( LastLineOfCell(aItemIndex) );
+
+    // If list was not scrolled, we update old focus cell and new focus cell. 
+    if (oldTopIndex == iTopItemIndex)
+        {
+        if (oldItemIndex != iCurrentItemIndex) 
+            {
+                DrawCell(oldItemIndex);
+                DrawCell(iCurrentItemIndex);
+            }
+        }
+    
+    TRACE_EXIT_POINT;
+    }
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::MoveCursorL
+//
+// (other items were commented in a header).
+// ----------------------------------------------------
+//
+void CCalenDayListBoxView::MoveCursorL(
+    TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
+    {
+    TRACE_ENTRY_POINT;
+
+    switch (aCursorMovement)
+        {
+        case CListBoxView::ECursorPreviousItem:
+            {
+            TInt prevLine(iCurrentItemIndex - 1);
+            if (prevLine >= 0)
+                {
+                TInt topLine = FirstLineOfCell(prevLine);
+                ScrollToItemL(topLine, aSelectionMode);
+                }
+            break;
+            }
+        case CListBoxView::ECursorNextItem:
+            {
+            TInt nextCell = LastLineOfCell(iCurrentItemIndex) + 1;
+            if (nextCell < iModel->NumberOfItems())
+                {
+                ScrollToItemL(nextCell, aSelectionMode);
+                }
+            break;
+            }
+        case CListBoxView::ECursorFirstItem:
+            {
+            TInt firstItem = 0;
+            if ( firstItem != iCurrentItemIndex) 
+            {
+            	ScrollToItemL(firstItem, aSelectionMode);
+            }
+            break;
+            }
+        case CListBoxView::ECursorLastItem:
+            {
+            TInt lastLine = iModel->NumberOfItems() - 1;
+            TInt lastItem = FirstLineOfCell(lastLine);
+            if ( lastItem != iCurrentItemIndex) 
+            {
+            	ScrollToItemL(lastItem, aSelectionMode);	
+            }
+            break;
+            }
+        default:
+            {
+            // Other TCursorMovements are not implemented. 
+            // Calling superclass's function would not work
+            break;
+            }
+        }
+    
+    TRACE_EXIT_POINT;
+    }
+
+
+// ----------------------------------------------------
+// CCalenDayListBoxView::MoveToItemL
+// Move to new event (from touch)
+// (other items were commented in a header).
+// ----------------------------------------------------
+//
+void CCalenDayListBoxView::MoveToItemL(TInt aItemIndex)
+    {
+    TRACE_ENTRY_POINT;
+    
+    if(AknLayoutUtils::PenEnabled())
+        {
+        TInt oldItemIndex = FirstLineOfCell(iCurrentItemIndex);
+        TInt oldTopIndex = iTopItemIndex;
+        
+        // To prevent incorrect drawing and flickering, we just move focus
+        // without updating the screen. Uikon list can't draw correct multirow 
+        // focus for us
+        // Updating is done below. 
+        SetDisableRedraw(ETrue);
+        VerticalMoveToItemL(FirstLineOfCell(aItemIndex), CListBoxView::ENoSelection);
+        SetDisableRedraw(EFalse);
+        
+        //These two scrolls ensure that all lines of item are visible.
+        //If list is scrolled, it is correctly updated and drawn by these methods
+        ScrollToMakeItemVisible( FirstLineOfCell(aItemIndex) );
+        ScrollToMakeItemVisible( LastLineOfCell(aItemIndex) );
+        
+        // If list was not scrolled, we update old focus cell and new focus cell. 
+        if (oldTopIndex == iTopItemIndex)
+            {
+            if (oldItemIndex != FirstLineOfCell(iCurrentItemIndex)) 
+                {
+                DrawCell(oldItemIndex);
+                DrawCell(FirstLineOfCell(iCurrentItemIndex));
+                }
+            }
+        }
+    
+    TRACE_EXIT_POINT;
+    }
+
+
+// End of File