uifw/EikStd/coctlsrc/AknDoubleSpanScrollIndicator.cpp
branchRCL_3
changeset 4 8ca85d2f0db7
parent 0 2f259fa3e83a
child 10 9f56a4e1b8ab
equal deleted inserted replaced
0:2f259fa3e83a 4:8ca85d2f0db7
    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
       
    37 
    32 
    38 CAknDoubleSpanScrollIndicator* CAknDoubleSpanScrollIndicator::NewL(CEikScrollBar::TOrientation aOrientation)
    33 CAknDoubleSpanScrollIndicator* CAknDoubleSpanScrollIndicator::NewL(CEikScrollBar::TOrientation aOrientation)
    39     {
    34     {
    40     CAknDoubleSpanScrollIndicator* self = new (ELeave) CAknDoubleSpanScrollIndicator();
    35     CAknDoubleSpanScrollIndicator* self = new (ELeave) CAknDoubleSpanScrollIndicator();
    41     CleanupStack::PushL(self);
    36     CleanupStack::PushL(self);
    44     return self;
    39     return self;
    45     }
    40     }
    46 
    41 
    47 CAknDoubleSpanScrollIndicator::CAknDoubleSpanScrollIndicator() 
    42 CAknDoubleSpanScrollIndicator::CAknDoubleSpanScrollIndicator() 
    48 : iOwnsWindow(EFalse), iTransparentBackground(EFalse), iDrawBackground(ETrue), 
    43 : iOwnsWindow(EFalse), iTransparentBackground(EFalse), iDrawBackground(ETrue), 
    49     iBackgroundHighlight(EFalse),iDrawBackgroundBitmap(EFalse)
    44     iBackgroundHighlight(EFalse)
    50     {
    45     {
    51     AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollIndicator" );
    46     AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollIndicator" );
    52     }
    47     }
    53 
    48 
    54 CAknDoubleSpanScrollIndicator::~CAknDoubleSpanScrollIndicator()
    49 CAknDoubleSpanScrollIndicator::~CAknDoubleSpanScrollIndicator()
   222         checkedWindowSize, 
   217         checkedWindowSize, 
   223         checkedFieldPosition, 
   218         checkedFieldPosition, 
   224         checkedFieldSize);
   219         checkedFieldSize);
   225     
   220     
   226     // If span (max number of items) is zero, then draw only the background
   221     // If span (max number of items) is zero, then draw only the background
   227     if (checkedScrollSpan == 0)
   222     if ( checkedScrollSpan == 0 || ( checkedScrollSpan <= checkedWindowSize ) )
   228         {
   223         {
       
   224         iBackgroundRect = TRect( 0, 0, 0, 0 );
   229         iHandleBackgroundRect = TRect(0,0,0,0);
   225         iHandleBackgroundRect = TRect(0,0,0,0);
   230         iHandleRect = TRect(0,0,0,0);
   226         iHandleRect = TRect(0,0,0,0);
   231         return;
   227         return;
   232         }
   228         }
   233 
   229 
   483         {
   479         {
   484         iOldRect = rect;        
   480         iOldRect = rect;        
   485         AknsUtils::RegisterControlPosition( this );
   481         AknsUtils::RegisterControlPosition( this );
   486         CalculateRects();
   482         CalculateRects();
   487 
   483 
   488         if (iOwnsWindow)
       
   489             {
       
   490             TRAP_IGNORE(CreateBackgroundBitmapL());
       
   491             }
       
   492         
       
   493         UpdateScrollBarLayout();
   484         UpdateScrollBarLayout();
   494         
   485         
   495         if (IsVisible() & iOwnsWindow)
   486         if (IsVisible() & iOwnsWindow)
   496             DrawDeferred();
   487             DrawDeferred();
   497         }
   488         }
   557     return iTransparentBackground;
   548     return iTransparentBackground;
   558     }
   549     }
   559 
   550 
   560 void CAknDoubleSpanScrollIndicator::HandleResourceChange(TInt aType)
   551 void CAknDoubleSpanScrollIndicator::HandleResourceChange(TInt aType)
   561     {
   552     {
   562     if ( aType == KAknsMessageSkinChange )
   553     if ( aType == KAknMessageFocusLost || KEikMessageUnfadeWindows == aType )
   563         {
       
   564         iDrawBackgroundBitmap = ETrue;
       
   565         }
       
   566     else if( aType == KAknMessageFocusLost || KEikMessageUnfadeWindows == aType)
       
   567         {
   554         {
   568         if( HandleHighlight() )
   555         if( HandleHighlight() )
   569             {
   556             {
   570             SetHandleHighlight(EFalse);
   557             SetHandleHighlight(EFalse);
   571             DrawDeferred();
   558             DrawDeferred();
   724 TBool CAknDoubleSpanScrollIndicator::DrawBackgroundState()
   711 TBool CAknDoubleSpanScrollIndicator::DrawBackgroundState()
   725     {
   712     {
   726     return iDrawBackground;
   713     return iDrawBackground;
   727     }
   714     }
   728 
   715 
   729 // Prepares background for window-owning scrollbar 
       
   730 void CAknDoubleSpanScrollIndicator::CreateBackgroundBitmapL()
       
   731     {
       
   732    
       
   733     }
       
   734 
   716 
   735 void CAknDoubleSpanScrollIndicator::DrawBackground() const
   717 void CAknDoubleSpanScrollIndicator::DrawBackground() const
   736     {
   718     {
   737     CWindowGc& gc=SystemGc();
   719     CWindowGc& gc=SystemGc();
   738     TPoint pos = Position();
   720     TPoint pos = Position();
   747             // Redraw the background to bitmap if the skin or the size is changed.
   729             // Redraw the background to bitmap if the skin or the size is changed.
   748             // Note that the indicator itself is not window owning but the actual window owning 
   730             // Note that the indicator itself is not window owning but the actual window owning 
   749             // component is the scrollbar class, therefore the window may be in different position
   731             // component is the scrollbar class, therefore the window may be in different position
   750             // and size than the indicator itself
   732             // and size than the indicator itself
   751             RWindow& win = Window();
   733             RWindow& win = Window();
   752             iDrawBackgroundBitmap = EFalse;
       
   753             TRect bmpRect(win.Position() + pos, rect.Size()); // There may be an arrow on top of scb
   734             TRect bmpRect(win.Position() + pos, rect.Size()); // There may be an arrow on top of scb
   754             if ( CAknEnv::Static()->TransparencyEnabled() )
   735 
   755                 {
   736             AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
   756                 AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
   737                 rect.iTl, bmpRect, KAknsDrawParamNoClearUnderImage );
   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                 }
       
   766             }
   738             }
   767         else             //SB is non-window-owning
   739         else             //SB is non-window-owning
   768             {
   740             {
   769             if ( CAknEnv::Static()->TransparencyEnabled() )
   741             AknsDrawUtils::Background( skin, cc, this, gc, rect, 
   770                 {
   742                     KAknsDrawParamNoClearUnderImage );
   771                 AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage );
       
   772                 }
       
   773             else
       
   774                 {
       
   775                 AknsDrawUtils::Background( skin, cc, this, gc, rect );
       
   776                 }
       
   777             }
   743             }
   778         }
   744         }
   779     }
   745     }
   780 
   746 
   781 void CAknDoubleSpanScrollIndicator::LayoutHandleGraphics()
   747 void CAknDoubleSpanScrollIndicator::LayoutHandleGraphics()
   825     else
   791     else
   826         {
   792         {
   827         iHandleRect.iTl.iY = rect.iTl.iY;
   793         iHandleRect.iTl.iY = rect.iTl.iY;
   828         iHandleRect.iBr.iY = rect.iBr.iY;
   794         iHandleRect.iBr.iY = rect.iBr.iY;
   829         }
   795         }
   830     
       
   831    
       
   832     }
   796     }
   833 
   797 
   834 TInt CAknDoubleSpanScrollIndicator::GetCurrentThumbSpanInPixels()
   798 TInt CAknDoubleSpanScrollIndicator::GetCurrentThumbSpanInPixels()
   835     {
   799     {
   836     return ( iOrientation == CEikScrollBar::EVertical ?
   800     return ( iOrientation == CEikScrollBar::EVertical ?
   866 TBool CAknDoubleSpanScrollIndicator::HandleHighlight() const
   830 TBool CAknDoubleSpanScrollIndicator::HandleHighlight() const
   867     {
   831     {
   868     return iHandleHighlight;
   832     return iHandleHighlight;
   869     }
   833     }
   870     
   834     
   871 void CAknDoubleSpanScrollIndicator::SetTouchAreaControl( CCoeControl* aTouchAreaControl )
   835 
   872     {
       
   873     iTouchAreaControl = aTouchAreaControl;
       
   874     }
       
   875   
       
   876  void CAknDoubleSpanScrollIndicator::SetBackgroudHighlight( TBool aBackgroudHighlight )
   836  void CAknDoubleSpanScrollIndicator::SetBackgroudHighlight( TBool aBackgroudHighlight )
   877     {
   837     {
   878     // This does nothing in non-touch
   838     // This does nothing in non-touch
   879     iBackgroundHighlight = aBackgroudHighlight;
   839     iBackgroundHighlight = aBackgroudHighlight;
   880 
       
   881     }
   840     }
   882     
   841     
   883 TBool CAknDoubleSpanScrollIndicator::BackgroudHighlight() const
   842 TBool CAknDoubleSpanScrollIndicator::BackgroudHighlight() const
   884     {
   843     {
   885     return iBackgroundHighlight;
   844     return iBackgroundHighlight;
   886     }
   845     }
   887 CFbsBitmap* CAknDoubleSpanScrollIndicator::CopyAndApplyEffectL(
   846 
   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