uifw/EikStd/coctlsrc/AknDoubleSpanScrollIndicator.cpp
branchRCL_3
changeset 19 aecbbf00d063
parent 10 3d340a0166ff
child 20 d48ab3b357f1
equal deleted inserted replaced
18:fcdfafb36fe7 19:aecbbf00d063
    27 #include <aknappui.h>
    27 #include <aknappui.h>
    28 #include <AknDef.h>
    28 #include <AknDef.h>
    29 #include <AknPriv.hrh>
    29 #include <AknPriv.hrh>
    30 #include <AknTasHook.h>
    30 #include <AknTasHook.h>
    31 #include <AknsDrawUtils.h>
    31 #include <AknsDrawUtils.h>
       
    32 // Do not use these constants directly, use implemented private methods instead.
       
    33 // const TInt KScrollBackgroundMinVisibleSizeInPixels = 4; // minimum distance handle and scb bottom. 
       
    34 //const TInt KHandleBackgroundMinSizeInPixels = 24; // double spanned non focused handle minimum size
       
    35 //const TInt KHandleMinSizeInPixels = 12; // focused handle minimum size
       
    36 const TInt KPrecision = 8; // Used in pixel effect calculations
    32 
    37 
    33 CAknDoubleSpanScrollIndicator* CAknDoubleSpanScrollIndicator::NewL(CEikScrollBar::TOrientation aOrientation)
    38 CAknDoubleSpanScrollIndicator* CAknDoubleSpanScrollIndicator::NewL(CEikScrollBar::TOrientation aOrientation)
    34     {
    39     {
    35     CAknDoubleSpanScrollIndicator* self = new (ELeave) CAknDoubleSpanScrollIndicator();
    40     CAknDoubleSpanScrollIndicator* self = new (ELeave) CAknDoubleSpanScrollIndicator();
    36     CleanupStack::PushL(self);
    41     CleanupStack::PushL(self);
    39     return self;
    44     return self;
    40     }
    45     }
    41 
    46 
    42 CAknDoubleSpanScrollIndicator::CAknDoubleSpanScrollIndicator() 
    47 CAknDoubleSpanScrollIndicator::CAknDoubleSpanScrollIndicator() 
    43 : iOwnsWindow(EFalse), iTransparentBackground(EFalse), iDrawBackground(ETrue), 
    48 : iOwnsWindow(EFalse), iTransparentBackground(EFalse), iDrawBackground(ETrue), 
    44     iBackgroundHighlight(EFalse)
    49     iBackgroundHighlight(EFalse),iDrawBackgroundBitmap(EFalse)
    45     {
    50     {
    46     AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollIndicator" );
    51     AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollIndicator" );
    47     }
    52     }
    48 
    53 
    49 CAknDoubleSpanScrollIndicator::~CAknDoubleSpanScrollIndicator()
    54 CAknDoubleSpanScrollIndicator::~CAknDoubleSpanScrollIndicator()
    67     }
    72     }
    68 
    73 
    69 void CAknDoubleSpanScrollIndicator::Draw(const TRect& /*aRect*/) const
    74 void CAknDoubleSpanScrollIndicator::Draw(const TRect& /*aRect*/) const
    70     {
    75     {
    71     CWindowGc& gc = SystemGc();
    76     CWindowGc& gc = SystemGc();
    72     if( iDrawBackground || iForceDrawBackground )
    77 
    73 
    78     if(iDrawBackground)
    74         {
    79         {
    75         DrawBackground();
    80         DrawBackground();
    76         }
    81         }
    77     
    82     
    78     CAknDoubleSpanScrollIndicatorItem* handleBackgroundBar = 
    83     CAknDoubleSpanScrollIndicatorItem* handleBackgroundBar = 
    91         iHandleHighlight && iHighlightHandleBar ?
    96         iHandleHighlight && iHighlightHandleBar ?
    92         iHighlightHandleBar : iHandleBar;
    97         iHighlightHandleBar : iHandleBar;
    93 
    98 
    94     DrawTiled(gc, iHandleRect, handleBar);
    99     DrawTiled(gc, iHandleRect, handleBar);
    95     }
   100     }
    96 
       
    97 void CAknDoubleSpanScrollIndicator::UpdateScrollBarLayout()
   101 void CAknDoubleSpanScrollIndicator::UpdateScrollBarLayout()
    98     {
   102     {
    99     iHeadItemSize = 12;
   103     iHeadItemSize = 12;
       
   104     iMidItemSize = 12 * 5;
   100     iTailItemSize = 12;
   105     iTailItemSize = 12;
   101     
   106     
   102     TRect rect( Rect() );
   107     TRect rect = Rect();
   103     if(rect.IsEmpty())
   108     if(rect.IsEmpty())
   104         {        
   109         {        
   105         return;
   110         return;
   106         }
   111         }
   107     
   112     
   112         }
   117         }
   113 
   118 
   114     TAknLayoutRect layRect;
   119     TAknLayoutRect layRect;
   115     TAknWindowComponentLayout layout = AknLayoutScalable_Avkon::scroll_bg_pane_g1( varietyIndex ); //top
   120     TAknWindowComponentLayout layout = AknLayoutScalable_Avkon::scroll_bg_pane_g1( varietyIndex ); //top
   116     layRect.LayoutRect( rect, layout.LayoutLine() );    
   121     layRect.LayoutRect( rect, layout.LayoutLine() );    
   117     TSize newSize( layRect.Rect().Size() );  
   122     TSize newSize = layRect.Rect().Size();  
   118     iHeadItemSize = (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth);
   123     iHeadItemSize = (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth);
   119     
   124     
   120     layout = AknLayoutScalable_Avkon::scroll_bg_pane_g3(varietyIndex); // bottom
   125     layout = AknLayoutScalable_Avkon::scroll_bg_pane_g3(varietyIndex); // bottom
   121     layRect.LayoutRect(rect, layout.LayoutLine());
   126     layRect.LayoutRect(rect, layout.LayoutLine());
   122     newSize = layRect.Rect().Size();
   127     newSize = layRect.Rect().Size();
   123     iTailItemSize =  (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth);
   128     iTailItemSize =  (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth);
       
   129         
       
   130     layout = AknLayoutScalable_Avkon::scroll_bg_pane_g2(varietyIndex); //middle
       
   131     layRect.LayoutRect(rect, layout.LayoutLine());
       
   132     newSize = layRect.Rect().Size();    
       
   133  //   iMidItemSize = (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth) * 5;
   124     }
   134     }
   125 
   135 
   126 void CAknDoubleSpanScrollIndicator::DrawTiled(
   136 void CAknDoubleSpanScrollIndicator::DrawTiled(
   127         CWindowGc& aGc, const TRect& aRect, 
   137         CWindowGc& aGc, const TRect& aRect, 
   128         CAknDoubleSpanScrollIndicatorItem *aIndicatorItem) const
   138         CAknDoubleSpanScrollIndicatorItem *aIndicatorItem) const
   148             tailRect.iTl.iY = tailRect.iBr.iY - headRect.Height();
   158             tailRect.iTl.iY = tailRect.iBr.iY - headRect.Height();
   149             }
   159             }
   150         midRect.iTl.iY += headRect.Height();
   160         midRect.iTl.iY += headRect.Height();
   151         midRect.iBr.iY -= tailRect.Height();
   161         midRect.iBr.iY -= tailRect.Height();
   152         midDrawLength = midRect.Height();
   162         midDrawLength = midRect.Height();
   153         midSize.SetSize(midRect.Width(), midDrawLength);
   163         midSize.SetSize(midRect.Width(), iMidItemSize);
   154         }
   164         }
   155     else
   165     else
   156         {
   166         {
   157         headRect.SetWidth( iHeadItemSize );
   167         headRect.SetWidth( iHeadItemSize );
   158         tailRect.iTl.iX = tailRect.iBr.iX - iTailItemSize;
   168         tailRect.iTl.iX = tailRect.iBr.iX - iTailItemSize;
   159 
   169 
   160         midRect.iTl.iX += iHeadItemSize;
   170         midRect.iTl.iX += iHeadItemSize;
   161         midRect.iBr.iX -= iTailItemSize;
   171         midRect.iBr.iX -= iTailItemSize;
   162         midDrawLength = midRect.Width();
   172         midDrawLength = midRect.Width();
   163         midSize.SetSize(midDrawLength, midRect.Height());
   173         midSize.SetSize(iMidItemSize, midRect.Height());
   164         }
   174         }
   165    
   175    
   166     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
   176     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
   167 
   177 
   168     CFbsBitmap *bmp = NULL; 
   178     CFbsBitmap *bmp = NULL; 
   169     CFbsBitmap *mask = NULL;
   179     CFbsBitmap *mask = NULL;
   170     AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iTopId, bmp, mask);
   180     AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iTopId, bmp, mask);
   171     AknIconUtils::SetSize(bmp, headRect.Size(), EAspectRatioNotPreserved);
   181     AknIconUtils::SetSize(bmp, headRect.Size(), EAspectRatioNotPreserved);
   172     AknIconUtils::SetSize(mask, headRect.Size(), EAspectRatioNotPreserved);
   182     AknIconUtils::SetSize(mask, headRect.Size(), EAspectRatioNotPreserved);
   173     aGc.BitBltMasked(headRect.iTl, bmp, TRect(headRect.Size()), mask, ETrue);
   183     aGc.BitBltMasked(headRect.iTl, bmp, TRect(TPoint(0, 0), headRect.Size()), mask, ETrue);
   174     
   184     
   175     AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iMidId, bmp, mask);
   185     AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iMidId, bmp, mask);
   176     AknIconUtils::SetSize(bmp, midSize, EAspectRatioNotPreserved);
   186     AknIconUtils::SetSize(bmp, midSize, EAspectRatioNotPreserved);
   177     AknIconUtils::SetSize(mask, midSize, EAspectRatioNotPreserved);
   187     AknIconUtils::SetSize(mask, midSize, EAspectRatioNotPreserved);
   178 
   188 
       
   189     TInt count = midDrawLength / iMidItemSize;
   179     TPoint destPos(midRect.iTl.iX, midRect.iTl.iY);
   190     TPoint destPos(midRect.iTl.iX, midRect.iTl.iY);
   180     TRect sourRect(bmp->SizeInPixels());
   191     TRect sourRect(TPoint(0, 0), bmp->SizeInPixels());
       
   192     for(TInt i = 0; i < count; i++)
       
   193         {
       
   194         aGc.BitBltMasked(destPos, bmp, sourRect, mask, ETrue);
       
   195         iOrientation == CEikScrollBar::EVertical?destPos.iY += iMidItemSize : destPos.iX += iMidItemSize;
       
   196         }
       
   197     iOrientation == CEikScrollBar::EVertical?sourRect.iBr.iY = midRect.Height() % iMidItemSize
       
   198                     :sourRect.iBr.iX = midRect.Width() % iMidItemSize;
   181     aGc.BitBltMasked(destPos, bmp, sourRect, mask, ETrue);
   199     aGc.BitBltMasked(destPos, bmp, sourRect, mask, ETrue);
   182 
   200 
   183     AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iBottomId, bmp, mask);
   201     AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iBottomId, bmp, mask);
   184     AknIconUtils::SetSize(bmp, tailRect.Size(), EAspectRatioNotPreserved);
   202     AknIconUtils::SetSize(bmp, tailRect.Size(), EAspectRatioNotPreserved);
   185     AknIconUtils::SetSize(mask, tailRect.Size(), EAspectRatioNotPreserved);
   203     AknIconUtils::SetSize(mask, tailRect.Size(), EAspectRatioNotPreserved);
   186     aGc.BitBltMasked(tailRect.iTl, bmp, TRect(tailRect.Size()), mask, ETrue);
   204     aGc.BitBltMasked(tailRect.iTl, bmp, TRect(TPoint(0, 0), tailRect.Size()), mask, ETrue);
   187     }
   205     }
   188 
   206 
   189 void CAknDoubleSpanScrollIndicator::CalculateRects()
   207 void CAknDoubleSpanScrollIndicator::CalculateRects()
   190     {
   208     {
   191     iBackgroundRect = Rect();
   209     iBackgroundRect = Rect();
   203         checkedFocusPosition, 
   221         checkedFocusPosition, 
   204         checkedWindowSize, 
   222         checkedWindowSize, 
   205         checkedFieldPosition, 
   223         checkedFieldPosition, 
   206         checkedFieldSize);
   224         checkedFieldSize);
   207     
   225     
   208     TBool wasEmpty = iBackgroundRect.IsEmpty();
       
   209     TBool isEmpty = EFalse;
       
   210 
       
   211     // If span (max number of items) is zero, then draw only the background
   226     // If span (max number of items) is zero, then draw only the background
   212     if ( checkedScrollSpan == 0 || ( checkedScrollSpan <= checkedWindowSize ) )
   227     if (checkedScrollSpan == 0)
   213         {
   228         {
   214         iBackgroundRect = TRect( 0, 0, 0, 0 );
       
   215         iHandleBackgroundRect = TRect(0,0,0,0);
   229         iHandleBackgroundRect = TRect(0,0,0,0);
   216         iHandleRect = TRect(0,0,0,0);
   230         iHandleRect = TRect(0,0,0,0);
   217         iForceDrawBackground = ETrue; // to enable background drawing
       
   218         isEmpty = ETrue;
       
   219         }
       
   220     else
       
   221         {
       
   222         iForceDrawBackground = EFalse;
       
   223         }
       
   224     if ( wasEmpty != isEmpty || iForceDrawBackground )
       
   225         {
       
   226         DrawDeferred();
       
   227         }
       
   228     
       
   229     if ( isEmpty )
       
   230         {
       
   231         return;
   231         return;
   232         }
   232         }
   233 
   233 
   234     // 
   234     // 
   235     // Transform values into pixels and rects.
   235     // Transform values into pixels and rects.
   243     else
   243     else
   244         {
   244         {
   245         scrollBarHeightInPixels = iBackgroundRect.Height();
   245         scrollBarHeightInPixels = iBackgroundRect.Height();
   246         }
   246         }
   247     
   247     
       
   248     // The code block below was probably used to prevent
       
   249     // a truncation-vs-rounding error from happening
       
   250     /*
       
   251     if ((checkedWindowSize > 0) && (checkedScrollSpan > 0))
       
   252         {
       
   253         if((checkedFocusPosition + checkedWindowSize) == checkedScrollSpan)
       
   254             windowSizeInPixels = scrollBarHeightInPixels - focusPositionInPixels;
       
   255         else
       
   256             windowSizeInPixels = scrollBarHeightInPixels*checkedWindowSize/checkedScrollSpan;
       
   257         }
       
   258     */
       
   259     
   248     TInt windowSizeInPixels = 
   260     TInt windowSizeInPixels = 
   249         Max( checkedWindowSize * scrollBarHeightInPixels / checkedScrollSpan,
   261         Max( checkedWindowSize * scrollBarHeightInPixels / checkedScrollSpan,
   250                 iHandleMinSize );
   262              HandleBackgroundMinSizeInPixels() );
   251     
   263     
   252     TInt roomForMovementInSpan   = checkedScrollSpan - checkedWindowSize;
   264     TInt roomForMovementInSpan   = checkedScrollSpan - checkedWindowSize;
   253     TInt roomForMovementInPixels = 
   265     TInt roomForMovementInPixels = 
   254         scrollBarHeightInPixels - windowSizeInPixels;    
   266         scrollBarHeightInPixels - windowSizeInPixels;    
   255     
   267     
   262             roomForMovementInSpan;
   274             roomForMovementInSpan;
   263         }
   275         }
   264 
   276 
   265     // If window would cover whole scrollbar, then modify 
   277     // If window would cover whole scrollbar, then modify 
   266     // it to leave the thumb little short from bottom
   278     // it to leave the thumb little short from bottom
   267     TInt scrollBarHandleMaxSizeInPixels =  iHandleMaxSize;
   279     TInt scrollBarHandleMaxSizeInPixels =  ScrollHandleMaxVisibleSizeInPixels();
   268 
       
   269     if (windowSizeInPixels >= scrollBarHeightInPixels)
   280     if (windowSizeInPixels >= scrollBarHeightInPixels)
   270         {
   281         {
   271         windowSizeInPixels = scrollBarHandleMaxSizeInPixels;    
   282         windowSizeInPixels = scrollBarHandleMaxSizeInPixels;    
   272         }
   283         }
   273 
   284 
   274     TBool doubleSpanInUse = (checkedFieldPosition >= 0) && (checkedFieldSize > 0);
   285     TBool doubleSpanInUse = (checkedFieldPosition >= 0) && (checkedFieldSize > 0);
   275     TInt minHandleBackgroundSize = iHandleMinSize;
   286     TInt minHandleBackgroundSize = 0;
   276     TInt fieldSizeInPixels = 0; // sub field size
   287     TInt fieldSizeInPixels = 0; // sub field size
   277     TInt fieldPositionInPixels = 0;
   288     TInt fieldPositionInPixels = 0;
   278     TInt handleMinSize = iHandleMinSize;
       
   279 
       
   280     if (doubleSpanInUse)
   289     if (doubleSpanInUse)
   281         {
   290         {
   282         fieldSizeInPixels = windowSizeInPixels/checkedFieldSize;
   291         fieldSizeInPixels = windowSizeInPixels/checkedFieldSize;
   283         fieldPositionInPixels = windowSizeInPixels*checkedFieldPosition/checkedFieldSize;
   292         fieldPositionInPixels = windowSizeInPixels*checkedFieldPosition/checkedFieldSize;
   284         }
   293         minHandleBackgroundSize = HandleBackgroundMinSizeInPixels();
   285 
   294         }
       
   295     else
       
   296         {
       
   297         minHandleBackgroundSize = HandleMinSizeInPixels();
       
   298         }
       
   299     
       
   300     TInt handleMinSize = HandleMinSizeInPixels();
   286     // Similar compensation for handle if double span is in use
   301     // Similar compensation for handle if double span is in use
   287     if (doubleSpanInUse && (fieldSizeInPixels < handleMinSize))
   302     if (doubleSpanInUse && (fieldSizeInPixels < handleMinSize))
   288         {
   303         {
   289         TInt extraPixels = 0;
   304         TInt extraPixels = 0;
   290         TInt extraPixelCompensationInterval = 0;
   305         TInt extraPixelCompensationInterval = 0;
   466     TRect rect( Rect() );
   481     TRect rect( Rect() );
   467     if(iOldRect != rect)
   482     if(iOldRect != rect)
   468         {
   483         {
   469         iOldRect = rect;        
   484         iOldRect = rect;        
   470         AknsUtils::RegisterControlPosition( this );
   485         AknsUtils::RegisterControlPosition( this );
   471         iHandleMinSize = HandleMinSizeInPixels();
       
   472         iHandleMaxSize = HandleMaxSizeInPixels();
       
   473         CalculateRects();
   486         CalculateRects();
       
   487 
       
   488         if (iOwnsWindow)
       
   489             {
       
   490             TRAP_IGNORE(CreateBackgroundBitmapL());
       
   491             }
       
   492         
   474         UpdateScrollBarLayout();
   493         UpdateScrollBarLayout();
   475 
   494         
   476         if (IsVisible() & iOwnsWindow)
   495         if (IsVisible() & iOwnsWindow)
   477             DrawDeferred();
   496             DrawDeferred();
   478         }
   497         }
   479     }
   498     }
   480 
   499 
   491     iScrollSpan = aScrollSpan;
   510     iScrollSpan = aScrollSpan;
   492     iFocusPosition = aFocusPosition;
   511     iFocusPosition = aFocusPosition;
   493     iWindowSize = aWindowSize;
   512     iWindowSize = aWindowSize;
   494     iFieldPosition = aFieldPosition;
   513     iFieldPosition = aFieldPosition;
   495     iFieldSize = aFieldSize;
   514     iFieldSize = aFieldSize;
   496 
   515     
   497     // Calculate the sizes for graphics
   516     // Calculate the sizes for graphics
   498     CalculateRects();            
   517     CalculateRects();            
       
   518     if( iWindowSize > 0 )
       
   519         {   
       
   520         // layout handle graphics
       
   521         LayoutHandleGraphics();
       
   522         }
   499     }
   523     }
   500 
   524 
   501 TInt CAknDoubleSpanScrollIndicator::ScrollSpan()
   525 TInt CAknDoubleSpanScrollIndicator::ScrollSpan()
   502     {
   526     {
   503     return iScrollSpan;
   527     return iScrollSpan;
   533     return iTransparentBackground;
   557     return iTransparentBackground;
   534     }
   558     }
   535 
   559 
   536 void CAknDoubleSpanScrollIndicator::HandleResourceChange(TInt aType)
   560 void CAknDoubleSpanScrollIndicator::HandleResourceChange(TInt aType)
   537     {
   561     {
   538     if ( aType == KAknMessageFocusLost || KEikMessageUnfadeWindows == aType )
   562     if ( aType == KAknsMessageSkinChange )
       
   563         {
       
   564         iDrawBackgroundBitmap = ETrue;
       
   565         }
       
   566     else if( aType == KAknMessageFocusLost || KEikMessageUnfadeWindows == aType)
   539         {
   567         {
   540         if( HandleHighlight() )
   568         if( HandleHighlight() )
   541             {
   569             {
   542             SetHandleHighlight(EFalse);
   570             SetHandleHighlight(EFalse);
   543             DrawDeferred();
   571             DrawDeferred();
   648         return layRect.Rect().Height();
   676         return layRect.Rect().Height();
   649     else
   677     else
   650         return layRect.Rect().Width();
   678         return layRect.Rect().Width();
   651     }
   679     }
   652 
   680 
   653 
   681 TInt CAknDoubleSpanScrollIndicator::ScrollHandleMaxVisibleSizeInPixels()
   654 TInt CAknDoubleSpanScrollIndicator::HandleMaxSizeInPixels()
   682     {
   655     {
   683     TRect scbRect = Rect();
   656     TRect scbRect( Rect() );
       
   657     if ( iOrientation == CEikScrollBar::EHorizontal )
   684     if ( iOrientation == CEikScrollBar::EHorizontal )
   658         scbRect.SetRect(scbRect.iTl, TSize(scbRect.Height(), scbRect.Width()));
   685         scbRect.SetRect(scbRect.iTl, TSize(scbRect.Height(), scbRect.Width()));
   659     
   686     
   660     TAknLayoutRect layRect;
   687     TAknLayoutRect layRect;
   661     TAknWindowComponentLayout layout = AknLayoutScalable_Avkon::aid_size_max_handle();
   688     TAknWindowComponentLayout layout = AknLayoutScalable_Avkon::aid_size_max_handle();
   662     layRect.LayoutRect(scbRect, layout.LayoutLine());
   689     layRect.LayoutRect(scbRect, layout.LayoutLine());
   663     return layRect.Rect().Height();
   690     return layRect.Rect().Height();
   664     }
   691     }
   665 
   692 
       
   693 TInt CAknDoubleSpanScrollIndicator::HandleBackgroundMinSizeInPixels()
       
   694     {
       
   695     return HandleMinSizeInPixels();
       
   696     }
   666 
   697 
   667 TInt CAknDoubleSpanScrollIndicator::HandleMinSizeInPixels()
   698 TInt CAknDoubleSpanScrollIndicator::HandleMinSizeInPixels()
   668     {
   699     {
   669     // We have the minimum size as aid value, do not layout to the handle layout as it is not correct
   700     // We have the minimum size as aid value, do not layout to the handle layout as it is not correct
   670     // on behalf of height argument (not set as maximum)
   701     // on behalf of height argument (not set as maximum)
   693 TBool CAknDoubleSpanScrollIndicator::DrawBackgroundState()
   724 TBool CAknDoubleSpanScrollIndicator::DrawBackgroundState()
   694     {
   725     {
   695     return iDrawBackground;
   726     return iDrawBackground;
   696     }
   727     }
   697 
   728 
       
   729 // Prepares background for window-owning scrollbar 
       
   730 void CAknDoubleSpanScrollIndicator::CreateBackgroundBitmapL()
       
   731     {
       
   732    
       
   733     }
   698 
   734 
   699 void CAknDoubleSpanScrollIndicator::DrawBackground() const
   735 void CAknDoubleSpanScrollIndicator::DrawBackground() const
   700     {
   736     {
   701     CWindowGc& gc=SystemGc();
   737     CWindowGc& gc=SystemGc();
   702     TPoint pos( Position() );
   738     TPoint pos = Position();
   703     TRect rect( Rect() );
   739     TRect rect = Rect();
   704     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
   740     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
   705     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
   741     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
   706     
   742     
   707     if(!iTransparentBackground)
   743     if(!iTransparentBackground)
   708         {
   744         {
   711             // Redraw the background to bitmap if the skin or the size is changed.
   747             // Redraw the background to bitmap if the skin or the size is changed.
   712             // Note that the indicator itself is not window owning but the actual window owning 
   748             // Note that the indicator itself is not window owning but the actual window owning 
   713             // component is the scrollbar class, therefore the window may be in different position
   749             // component is the scrollbar class, therefore the window may be in different position
   714             // and size than the indicator itself
   750             // and size than the indicator itself
   715             RWindow& win = Window();
   751             RWindow& win = Window();
       
   752             iDrawBackgroundBitmap = EFalse;
   716             TRect bmpRect(win.Position() + pos, rect.Size()); // There may be an arrow on top of scb
   753             TRect bmpRect(win.Position() + pos, rect.Size()); // There may be an arrow on top of scb
   717 
   754             if ( CAknEnv::Static()->TransparencyEnabled() )
   718             AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
   755                 {
   719                 rect.iTl, bmpRect, KAknsDrawParamNoClearUnderImage );
   756                 AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
       
   757                     rect.iTl, bmpRect, KAknsDrawParamNoClearUnderImage );
       
   758                 }
       
   759             else
       
   760                 {
       
   761                 AknsDrawUtils::DrawBackground( skin, cc, NULL, gc, 
       
   762                     TPoint(0,0), bmpRect , KAknsDrawParamNoClearUnderImage );
       
   763                     
       
   764                          
       
   765                 }
   720             }
   766             }
   721         else             //SB is non-window-owning
   767         else             //SB is non-window-owning
   722             {
   768             {
   723             AknsDrawUtils::Background( skin, cc, this, gc, rect, 
   769             if ( CAknEnv::Static()->TransparencyEnabled() )
   724                     KAknsDrawParamNoClearUnderImage );
   770                 {
   725             }
   771                 AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage );
   726         }
   772                 }
   727     }
   773             else
   728 
   774                 {
       
   775                 AknsDrawUtils::Background( skin, cc, this, gc, rect );
       
   776                 }
       
   777             }
       
   778         }
       
   779     }
       
   780 
       
   781 void CAknDoubleSpanScrollIndicator::LayoutHandleGraphics()
       
   782     {
       
   783     
       
   784     // We layout the handle middle graphics here according to the given inidcator values
       
   785     TRect rect = Rect();
       
   786     
       
   787     if (!iHandleBar || rect.IsEmpty())
       
   788         return;
       
   789     
       
   790     TInt varietyIndex = 0;
       
   791     TInt varietyIndexForHandle = 0;
       
   792     if (iOrientation == CEikScrollBar::EHorizontal)
       
   793         {        
       
   794         varietyIndex = 1;
       
   795         varietyIndexForHandle = 2;
       
   796         }
       
   797     
       
   798     TAknLayoutRect layRect;
       
   799     TAknWindowComponentLayout // layout handle bottom & top as they do not scale according to handle size
       
   800     layout = AknLayoutScalable_Avkon::scroll_handle_pane(varietyIndexForHandle); // handle (the shadow if two handles)
       
   801     layRect.LayoutRect(rect, layout.LayoutLine());
       
   802     layout = AknLayoutScalable_Avkon::scroll_handle_focus_pane(varietyIndex); // focus handle
       
   803     // The horizontal data for focus handle is missing so switch the values from the vertical data
       
   804     TAknWindowLineLayout layoutLine = layout.LayoutLine();
       
   805     if (iOrientation == CEikScrollBar::EHorizontal)
       
   806         {
       
   807         TInt height = layoutLine.iH;
       
   808         TInt width = layoutLine.iW;
       
   809         layoutLine.iW = height;
       
   810         layoutLine.iH = width;
       
   811         }
       
   812     layRect.LayoutRect(layRect.Rect(), layoutLine);
       
   813     rect = layRect.Rect(); // parent rect is now the focus handle
       
   814     
       
   815     // the retangle includes the variated length of the middle, 
       
   816     // the top and bottom graphics must subtracted from the value
       
   817     
       
   818     // do not change the handle retangle, the full size is needed in drawing
       
   819     // set the width or height to be correct
       
   820     if (iOrientation == CEikScrollBar::EVertical)
       
   821         {
       
   822         iHandleRect.iTl.iX = rect.iTl.iX;
       
   823         iHandleRect.iBr.iX = rect.iBr.iX;
       
   824         }
       
   825     else
       
   826         {
       
   827         iHandleRect.iTl.iY = rect.iTl.iY;
       
   828         iHandleRect.iBr.iY = rect.iBr.iY;
       
   829         }
       
   830     
       
   831    
       
   832     }
   729 
   833 
   730 TInt CAknDoubleSpanScrollIndicator::GetCurrentThumbSpanInPixels()
   834 TInt CAknDoubleSpanScrollIndicator::GetCurrentThumbSpanInPixels()
   731     {
   835     {
   732     return ( iOrientation == CEikScrollBar::EVertical ?
   836     return ( iOrientation == CEikScrollBar::EVertical ?
   733              iHandleBackgroundRect.Height() :
   837              iHandleBackgroundRect.Height() :
   762 TBool CAknDoubleSpanScrollIndicator::HandleHighlight() const
   866 TBool CAknDoubleSpanScrollIndicator::HandleHighlight() const
   763     {
   867     {
   764     return iHandleHighlight;
   868     return iHandleHighlight;
   765     }
   869     }
   766     
   870     
   767 
   871 void CAknDoubleSpanScrollIndicator::SetTouchAreaControl( CCoeControl* aTouchAreaControl )
       
   872     {
       
   873     iTouchAreaControl = aTouchAreaControl;
       
   874     }
       
   875   
   768  void CAknDoubleSpanScrollIndicator::SetBackgroudHighlight( TBool aBackgroudHighlight )
   876  void CAknDoubleSpanScrollIndicator::SetBackgroudHighlight( TBool aBackgroudHighlight )
   769     {
   877     {
   770     // This does nothing in non-touch
   878     // This does nothing in non-touch
   771     iBackgroundHighlight = aBackgroudHighlight;
   879     iBackgroundHighlight = aBackgroudHighlight;
       
   880 
   772     }
   881     }
   773     
   882     
   774 TBool CAknDoubleSpanScrollIndicator::BackgroudHighlight() const
   883 TBool CAknDoubleSpanScrollIndicator::BackgroudHighlight() const
   775     {
   884     {
   776     return iBackgroundHighlight;
   885     return iBackgroundHighlight;
   777     }
   886     }
   778 
   887 CFbsBitmap* CAknDoubleSpanScrollIndicator::CopyAndApplyEffectL(
       
   888     const CFbsBitmap* aSource, TBool aCopyOnly )
       
   889     {
       
   890     CFbsBitmap* newBitmap = NULL;
       
   891     
       
   892     
       
   893         newBitmap = new ( ELeave ) CFbsBitmap; 
       
   894     
       
   895     
       
   896     
       
   897     TInt err = newBitmap->Create( aSource->SizeInPixels(), aSource->DisplayMode() );
       
   898     
       
   899     // We still have to return a dummy bitmap object, even if
       
   900     // the creation fails.
       
   901     if ( err == KErrNone )
       
   902         {
       
   903         SEpocBitmapHeader header = aSource->Header();
       
   904         
       
   905         // We support only 16-bit (5-6-5), since this is the default
       
   906         // display mode icons are created in. Otherwise just copy.
       
   907         if ( !aCopyOnly && aSource->DisplayMode() == EColor64K )
       
   908             {
       
   909             // Don't modify header data.
       
   910             TInt size = ( header.iBitmapSize - header.iStructSize ) /
       
   911                         sizeof( TUint16 );
       
   912                         
       
   913             aSource->BeginDataAccess();
       
   914         
       
   915             TUint16* source = (TUint16*)aSource->DataAddress();
       
   916             TUint16* dest = (TUint16*)newBitmap->DataAddress();
       
   917             
       
   918             for ( TInt i = 0; i < size; ++i )
       
   919                 {
       
   920                 *dest = *source++;
       
   921                 TBitmapFx::PixelEffect( dest++ );
       
   922                 }
       
   923             
       
   924             aSource->EndDataAccess( ETrue );
       
   925             }
       
   926         else
       
   927             {
       
   928             // This is probably faster than blitting it. Copy
       
   929             // the header data in the same run to minimize size
       
   930             // calculations, although it's already correct in the
       
   931             // new bitmap.
       
   932             TInt size = aSource->Header().iBitmapSize;
       
   933 
       
   934             aSource->BeginDataAccess();
       
   935             
       
   936             Mem::Copy( newBitmap->DataAddress(),
       
   937                        aSource->DataAddress(),
       
   938                        size );
       
   939                        
       
   940             aSource->EndDataAccess( ETrue );
       
   941             }
       
   942         }
       
   943     
       
   944     
       
   945     return newBitmap;
       
   946     }
       
   947 
       
   948 
       
   949 void TBitmapFx::PixelEffect( TUint16* aPixelData )
       
   950     {
       
   951     // Note: the calculations in this function are based on
       
   952     // graphic designers' conception of what Photoshop does
       
   953     // to images with certain values. There might also be some
       
   954     // room for optimizations.
       
   955     
       
   956     TRGB rgb;
       
   957     
       
   958     rgb.iR = ( *aPixelData & 0xF800 ) >> 11;
       
   959     rgb.iG = ( *aPixelData & 0x7E0 ) >> 5;
       
   960     rgb.iB = ( *aPixelData & 0x1F );
       
   961     
       
   962     // Scale to 65280 (0xFF00). Under no circumstances should these
       
   963     // values end up being > 0xFF00 or < 0x00
       
   964     rgb.iR *= 2105.82f;
       
   965     rgb.iG *= 1036.20f;
       
   966     rgb.iB *= 2105.82f;
       
   967     
       
   968     // Convert RGB to HSL
       
   969     TInt min = Min( rgb.iR, Min( rgb.iG, rgb.iB ) );
       
   970     TInt max = Max( rgb.iR, Max( rgb.iG, rgb.iB ) );
       
   971     TInt delta = max - min;
       
   972 
       
   973     THSL hsl = { 0, 0, 0 } ;
       
   974     
       
   975     // Lightness
       
   976     hsl.iL = ( max + min ) >> 1;
       
   977     
       
   978     if ( delta == 0 )
       
   979         {
       
   980         hsl.iH = 0;
       
   981         hsl.iS = 0;
       
   982         }
       
   983     else
       
   984         {
       
   985         // Hue
       
   986         if ( max == rgb.iR )
       
   987             {
       
   988             hsl.iH = 10880 * ( rgb.iG - rgb.iB ) / delta;
       
   989             }
       
   990         else if ( max == rgb.iG )
       
   991             {
       
   992             hsl.iH = 10880 * ( rgb.iB - rgb.iR ) / delta + 21760;
       
   993             }
       
   994         else if ( max == rgb.iB )
       
   995             {
       
   996             hsl.iH = 10880 * ( rgb.iR - rgb.iG ) / delta + 43520;
       
   997             }
       
   998         
       
   999         // Saturation
       
  1000         if ( hsl.iL <= 32640 )
       
  1001             {
       
  1002             hsl.iS = ( delta << KPrecision ) / ( ( max + min ) >> KPrecision );
       
  1003             }
       
  1004         else
       
  1005             {
       
  1006             hsl.iS = ( delta << KPrecision ) / ( ( 0x1FE00 - ( max + min ) ) >> KPrecision );
       
  1007             }
       
  1008         }
       
  1009 
       
  1010     // Apply hue shift, moved to proper range in HueToRGB()
       
  1011     hsl.iH += 0x715;
       
  1012         
       
  1013     // Apply saturation
       
  1014     // +10 in -100..100 in Photoshop terms. According to related material
       
  1015     // corresponds to 0xCC0 when applied to 0x00..0xFF00
       
  1016     hsl.iS += 0xCC0;
       
  1017     
       
  1018     if ( hsl.iS > 0xFF00 )
       
  1019         {
       
  1020         hsl.iS = 0xFF00;
       
  1021         }
       
  1022 
       
  1023     // Convert back to RGB
       
  1024     TInt v1;
       
  1025     TInt v2;
       
  1026     
       
  1027     if ( hsl.iS == 0 )
       
  1028         {
       
  1029         rgb.iR = ( hsl.iL * 255 ) >> KPrecision;
       
  1030         rgb.iG = ( hsl.iL * 255 ) >> KPrecision;
       
  1031         rgb.iB = ( hsl.iL * 255 ) >> KPrecision;
       
  1032         }
       
  1033     else
       
  1034         {
       
  1035         if ( hsl.iL < 32640 )
       
  1036             {
       
  1037             v2 = ( hsl.iL  * ( ( 0xFF00 + hsl.iS ) >> KPrecision ) ) >> KPrecision;
       
  1038             }
       
  1039         else
       
  1040             {
       
  1041             v2 = ( hsl.iL + hsl.iS ) - ( ( hsl.iS >> KPrecision ) * ( hsl.iL >> KPrecision ) );
       
  1042             }
       
  1043         
       
  1044         v1 = 2 * hsl.iL - v2;
       
  1045       
       
  1046         rgb.iR = ( HueToRGB( v1, v2, hsl.iH + 0x54FF ) );
       
  1047         rgb.iG = ( HueToRGB( v1, v2, hsl.iH ) );
       
  1048         rgb.iB = ( HueToRGB( v1, v2, hsl.iH - 0x54FF ) );
       
  1049         }
       
  1050 
       
  1051     rgb.iR /= 2105.82f;
       
  1052     rgb.iG /= 1036.20f;
       
  1053     rgb.iB /= 2105.82f;
       
  1054 
       
  1055     // Apply contrast.. However, the original req stated that the
       
  1056     // contrast value should be +6 in a range of -100..100.
       
  1057     // With 5 and 6 bit values and fixed point math such a small value has
       
  1058     // no effect, so it has been left out. The code is here in case
       
  1059     // the contrast value is updated at some point.
       
  1060     /*
       
  1061     const TInt contrast   = ( 6 * 65536 / 200 ) + 65536;
       
  1062     
       
  1063     rgb.iR -= 15;
       
  1064     rgb.iG -= 31;
       
  1065     rgb.iB -= 15;
       
  1066     
       
  1067     rgb.iR *= contrast;
       
  1068     rgb.iG *= contrast;
       
  1069     rgb.iB *= contrast;
       
  1070     
       
  1071     rgb.iR /= 65536;
       
  1072     rgb.iG /= 65536;
       
  1073     rgb.iB /= 65536;
       
  1074 
       
  1075     rgb.iR += 15;
       
  1076     rgb.iG += 31;
       
  1077     rgb.iB += 15;
       
  1078     */
       
  1079 
       
  1080     // Apply brightness, -40 in a range of -100..100 for
       
  1081     // 0..255 rgb values, which corresponds to -5 for 5 bit
       
  1082     // and -10 for 6 bit rgb values.
       
  1083     rgb.iR -= 5;
       
  1084     rgb.iG -= 10;
       
  1085     rgb.iB -= 5;
       
  1086 
       
  1087     if ( rgb.iR < 0 ) rgb.iR = 0;
       
  1088     if ( rgb.iG < 0 ) rgb.iG = 0;
       
  1089     if ( rgb.iB < 0 ) rgb.iB = 0;
       
  1090     
       
  1091     if ( rgb.iR > 31 ) rgb.iR = 31;
       
  1092     if ( rgb.iG > 63 ) rgb.iG = 63;
       
  1093     if ( rgb.iB > 31 ) rgb.iB = 31;
       
  1094 
       
  1095     *aPixelData =
       
  1096         ( rgb.iB | ( rgb.iG << 5 ) | ( rgb.iR << 11 ) );
       
  1097     }
       
  1098     
       
  1099 TInt TBitmapFx::HueToRGB( TInt v1, TInt v2, TInt aH )
       
  1100     {
       
  1101     while ( aH < 0 )
       
  1102         {
       
  1103         aH += 0xFF00;
       
  1104         }
       
  1105         
       
  1106     while ( aH >= 0xFF00 )
       
  1107         {
       
  1108         aH -= 0xFF00;
       
  1109         }
       
  1110         
       
  1111     if ( ( ( 6 * aH ) ) < 0xFF00 )
       
  1112         {
       
  1113         return v1 + ( ( v2 - v1 ) * ( ( 6 * aH ) >> KPrecision ) >> KPrecision );
       
  1114         }
       
  1115 
       
  1116     if ( ( ( 2 * aH ) ) < 0xFF00 )
       
  1117         {
       
  1118         return v2;
       
  1119         }
       
  1120 
       
  1121     if ( ( ( 3 * aH ) ) < 0x1FE00 )
       
  1122         {
       
  1123         return v1 + ( ( v2 - v1 ) * ( ( ( 0xA9FF - aH ) * 6 ) >> KPrecision ) >> KPrecision );
       
  1124         }
       
  1125     
       
  1126     return v1;
       
  1127     }
       
  1128