--- a/uifw/EikStd/coctlsrc/AknDoubleSpanScrollIndicator.cpp Tue Aug 31 15:28:30 2010 +0300
+++ b/uifw/EikStd/coctlsrc/AknDoubleSpanScrollIndicator.cpp Wed Sep 01 12:16:19 2010 +0100
@@ -29,11 +29,6 @@
#include <AknPriv.hrh>
#include <AknTasHook.h>
#include <AknsDrawUtils.h>
-// Do not use these constants directly, use implemented private methods instead.
-// const TInt KScrollBackgroundMinVisibleSizeInPixels = 4; // minimum distance handle and scb bottom.
-//const TInt KHandleBackgroundMinSizeInPixels = 24; // double spanned non focused handle minimum size
-//const TInt KHandleMinSizeInPixels = 12; // focused handle minimum size
-const TInt KPrecision = 8; // Used in pixel effect calculations
CAknDoubleSpanScrollIndicator* CAknDoubleSpanScrollIndicator::NewL(CEikScrollBar::TOrientation aOrientation)
{
@@ -46,7 +41,7 @@
CAknDoubleSpanScrollIndicator::CAknDoubleSpanScrollIndicator()
: iOwnsWindow(EFalse), iTransparentBackground(EFalse), iDrawBackground(ETrue),
- iBackgroundHighlight(EFalse),iDrawBackgroundBitmap(EFalse)
+ iBackgroundHighlight(EFalse)
{
AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollIndicator" );
}
@@ -74,8 +69,8 @@
void CAknDoubleSpanScrollIndicator::Draw(const TRect& /*aRect*/) const
{
CWindowGc& gc = SystemGc();
+ if( iDrawBackground || iForceDrawBackground )
- if(iDrawBackground)
{
DrawBackground();
}
@@ -98,13 +93,13 @@
DrawTiled(gc, iHandleRect, handleBar);
}
+
void CAknDoubleSpanScrollIndicator::UpdateScrollBarLayout()
{
iHeadItemSize = 12;
- iMidItemSize = 12 * 5;
iTailItemSize = 12;
- TRect rect = Rect();
+ TRect rect( Rect() );
if(rect.IsEmpty())
{
return;
@@ -119,18 +114,13 @@
TAknLayoutRect layRect;
TAknWindowComponentLayout layout = AknLayoutScalable_Avkon::scroll_bg_pane_g1( varietyIndex ); //top
layRect.LayoutRect( rect, layout.LayoutLine() );
- TSize newSize = layRect.Rect().Size();
+ TSize newSize( layRect.Rect().Size() );
iHeadItemSize = (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth);
layout = AknLayoutScalable_Avkon::scroll_bg_pane_g3(varietyIndex); // bottom
layRect.LayoutRect(rect, layout.LayoutLine());
newSize = layRect.Rect().Size();
iTailItemSize = (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth);
-
- layout = AknLayoutScalable_Avkon::scroll_bg_pane_g2(varietyIndex); //middle
- layRect.LayoutRect(rect, layout.LayoutLine());
- newSize = layRect.Rect().Size();
- // iMidItemSize = (iOrientation == CEikScrollBar::EVertical?newSize.iHeight:newSize.iWidth) * 5;
}
void CAknDoubleSpanScrollIndicator::DrawTiled(
@@ -160,7 +150,7 @@
midRect.iTl.iY += headRect.Height();
midRect.iBr.iY -= tailRect.Height();
midDrawLength = midRect.Height();
- midSize.SetSize(midRect.Width(), iMidItemSize);
+ midSize.SetSize(midRect.Width(), midDrawLength);
}
else
{
@@ -170,7 +160,7 @@
midRect.iTl.iX += iHeadItemSize;
midRect.iBr.iX -= iTailItemSize;
midDrawLength = midRect.Width();
- midSize.SetSize(iMidItemSize, midRect.Height());
+ midSize.SetSize(midDrawLength, midRect.Height());
}
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
@@ -180,28 +170,20 @@
AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iTopId, bmp, mask);
AknIconUtils::SetSize(bmp, headRect.Size(), EAspectRatioNotPreserved);
AknIconUtils::SetSize(mask, headRect.Size(), EAspectRatioNotPreserved);
- aGc.BitBltMasked(headRect.iTl, bmp, TRect(TPoint(0, 0), headRect.Size()), mask, ETrue);
+ aGc.BitBltMasked(headRect.iTl, bmp, TRect(headRect.Size()), mask, ETrue);
AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iMidId, bmp, mask);
AknIconUtils::SetSize(bmp, midSize, EAspectRatioNotPreserved);
AknIconUtils::SetSize(mask, midSize, EAspectRatioNotPreserved);
- TInt count = midDrawLength / iMidItemSize;
TPoint destPos(midRect.iTl.iX, midRect.iTl.iY);
- TRect sourRect(TPoint(0, 0), bmp->SizeInPixels());
- for(TInt i = 0; i < count; i++)
- {
- aGc.BitBltMasked(destPos, bmp, sourRect, mask, ETrue);
- iOrientation == CEikScrollBar::EVertical?destPos.iY += iMidItemSize : destPos.iX += iMidItemSize;
- }
- iOrientation == CEikScrollBar::EVertical?sourRect.iBr.iY = midRect.Height() % iMidItemSize
- :sourRect.iBr.iX = midRect.Width() % iMidItemSize;
+ TRect sourRect(bmp->SizeInPixels());
aGc.BitBltMasked(destPos, bmp, sourRect, mask, ETrue);
AknsUtils::GetCachedMaskedBitmap(skin, aIndicatorItem->iBottomId, bmp, mask);
AknIconUtils::SetSize(bmp, tailRect.Size(), EAspectRatioNotPreserved);
AknIconUtils::SetSize(mask, tailRect.Size(), EAspectRatioNotPreserved);
- aGc.BitBltMasked(tailRect.iTl, bmp, TRect(TPoint(0, 0), tailRect.Size()), mask, ETrue);
+ aGc.BitBltMasked(tailRect.iTl, bmp, TRect(tailRect.Size()), mask, ETrue);
}
void CAknDoubleSpanScrollIndicator::CalculateRects()
@@ -223,11 +205,29 @@
checkedFieldPosition,
checkedFieldSize);
+ TBool wasEmpty = iBackgroundRect.IsEmpty();
+ TBool isEmpty = EFalse;
+
// If span (max number of items) is zero, then draw only the background
- if (checkedScrollSpan == 0)
+ if ( checkedScrollSpan == 0 || ( checkedScrollSpan <= checkedWindowSize ) )
{
+ iBackgroundRect = TRect( 0, 0, 0, 0 );
iHandleBackgroundRect = TRect(0,0,0,0);
iHandleRect = TRect(0,0,0,0);
+ iForceDrawBackground = ETrue; // to enable background drawing
+ isEmpty = ETrue;
+ }
+ else
+ {
+ iForceDrawBackground = EFalse;
+ }
+ if ( wasEmpty != isEmpty || iForceDrawBackground )
+ {
+ DrawDeferred();
+ }
+
+ if ( isEmpty )
+ {
return;
}
@@ -245,21 +245,9 @@
scrollBarHeightInPixels = iBackgroundRect.Height();
}
- // The code block below was probably used to prevent
- // a truncation-vs-rounding error from happening
- /*
- if ((checkedWindowSize > 0) && (checkedScrollSpan > 0))
- {
- if((checkedFocusPosition + checkedWindowSize) == checkedScrollSpan)
- windowSizeInPixels = scrollBarHeightInPixels - focusPositionInPixels;
- else
- windowSizeInPixels = scrollBarHeightInPixels*checkedWindowSize/checkedScrollSpan;
- }
- */
-
TInt windowSizeInPixels =
Max( checkedWindowSize * scrollBarHeightInPixels / checkedScrollSpan,
- HandleBackgroundMinSizeInPixels() );
+ iHandleMinSize );
TInt roomForMovementInSpan = checkedScrollSpan - checkedWindowSize;
TInt roomForMovementInPixels =
@@ -276,28 +264,25 @@
// If window would cover whole scrollbar, then modify
// it to leave the thumb little short from bottom
- TInt scrollBarHandleMaxSizeInPixels = ScrollHandleMaxVisibleSizeInPixels();
+ TInt scrollBarHandleMaxSizeInPixels = iHandleMaxSize;
+
if (windowSizeInPixels >= scrollBarHeightInPixels)
{
windowSizeInPixels = scrollBarHandleMaxSizeInPixels;
}
TBool doubleSpanInUse = (checkedFieldPosition >= 0) && (checkedFieldSize > 0);
- TInt minHandleBackgroundSize = 0;
+ TInt minHandleBackgroundSize = iHandleMinSize;
TInt fieldSizeInPixels = 0; // sub field size
TInt fieldPositionInPixels = 0;
+ TInt handleMinSize = iHandleMinSize;
+
if (doubleSpanInUse)
{
fieldSizeInPixels = windowSizeInPixels/checkedFieldSize;
fieldPositionInPixels = windowSizeInPixels*checkedFieldPosition/checkedFieldSize;
- minHandleBackgroundSize = HandleBackgroundMinSizeInPixels();
}
- else
- {
- minHandleBackgroundSize = HandleMinSizeInPixels();
- }
-
- TInt handleMinSize = HandleMinSizeInPixels();
+
// Similar compensation for handle if double span is in use
if (doubleSpanInUse && (fieldSizeInPixels < handleMinSize))
{
@@ -483,15 +468,11 @@
{
iOldRect = rect;
AknsUtils::RegisterControlPosition( this );
+ iHandleMinSize = HandleMinSizeInPixels();
+ iHandleMaxSize = HandleMaxSizeInPixels();
CalculateRects();
+ UpdateScrollBarLayout();
- if (iOwnsWindow)
- {
- TRAP_IGNORE(CreateBackgroundBitmapL());
- }
-
- UpdateScrollBarLayout();
-
if (IsVisible() & iOwnsWindow)
DrawDeferred();
}
@@ -512,14 +493,9 @@
iWindowSize = aWindowSize;
iFieldPosition = aFieldPosition;
iFieldSize = aFieldSize;
-
+
// Calculate the sizes for graphics
CalculateRects();
- if( iWindowSize > 0 )
- {
- // layout handle graphics
- LayoutHandleGraphics();
- }
}
TInt CAknDoubleSpanScrollIndicator::ScrollSpan()
@@ -559,11 +535,7 @@
void CAknDoubleSpanScrollIndicator::HandleResourceChange(TInt aType)
{
- if ( aType == KAknsMessageSkinChange )
- {
- iDrawBackgroundBitmap = ETrue;
- }
- else if( aType == KAknMessageFocusLost || KEikMessageUnfadeWindows == aType)
+ if ( aType == KAknMessageFocusLost || KEikMessageUnfadeWindows == aType )
{
if( HandleHighlight() )
{
@@ -678,9 +650,10 @@
return layRect.Rect().Width();
}
-TInt CAknDoubleSpanScrollIndicator::ScrollHandleMaxVisibleSizeInPixels()
+
+TInt CAknDoubleSpanScrollIndicator::HandleMaxSizeInPixels()
{
- TRect scbRect = Rect();
+ TRect scbRect( Rect() );
if ( iOrientation == CEikScrollBar::EHorizontal )
scbRect.SetRect(scbRect.iTl, TSize(scbRect.Height(), scbRect.Width()));
@@ -690,10 +663,6 @@
return layRect.Rect().Height();
}
-TInt CAknDoubleSpanScrollIndicator::HandleBackgroundMinSizeInPixels()
- {
- return HandleMinSizeInPixels();
- }
TInt CAknDoubleSpanScrollIndicator::HandleMinSizeInPixels()
{
@@ -726,17 +695,12 @@
return iDrawBackground;
}
-// Prepares background for window-owning scrollbar
-void CAknDoubleSpanScrollIndicator::CreateBackgroundBitmapL()
- {
-
- }
void CAknDoubleSpanScrollIndicator::DrawBackground() const
{
CWindowGc& gc=SystemGc();
- TPoint pos = Position();
- TRect rect = Rect();
+ TPoint pos( Position() );
+ TRect rect( Rect() );
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
@@ -749,87 +713,19 @@
// component is the scrollbar class, therefore the window may be in different position
// and size than the indicator itself
RWindow& win = Window();
- iDrawBackgroundBitmap = EFalse;
TRect bmpRect(win.Position() + pos, rect.Size()); // There may be an arrow on top of scb
- if ( CAknEnv::Static()->TransparencyEnabled() )
- {
- AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
- rect.iTl, bmpRect, KAknsDrawParamNoClearUnderImage );
- }
- else
- {
- AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
- TPoint(0,0), bmpRect , KAknsDrawParamNoClearUnderImage );
-
-
- }
+
+ AknsDrawUtils::DrawBackground( skin, cc, NULL, gc,
+ rect.iTl, bmpRect, KAknsDrawParamNoClearUnderImage );
}
else //SB is non-window-owning
{
- if ( CAknEnv::Static()->TransparencyEnabled() )
- {
- AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage );
- }
- else
- {
- AknsDrawUtils::Background( skin, cc, this, gc, rect );
- }
+ AknsDrawUtils::Background( skin, cc, this, gc, rect,
+ KAknsDrawParamNoClearUnderImage );
}
}
}
-void CAknDoubleSpanScrollIndicator::LayoutHandleGraphics()
- {
-
- // We layout the handle middle graphics here according to the given inidcator values
- TRect rect = Rect();
-
- if (!iHandleBar || rect.IsEmpty())
- return;
-
- TInt varietyIndex = 0;
- TInt varietyIndexForHandle = 0;
- if (iOrientation == CEikScrollBar::EHorizontal)
- {
- varietyIndex = 1;
- varietyIndexForHandle = 2;
- }
-
- TAknLayoutRect layRect;
- TAknWindowComponentLayout // layout handle bottom & top as they do not scale according to handle size
- layout = AknLayoutScalable_Avkon::scroll_handle_pane(varietyIndexForHandle); // handle (the shadow if two handles)
- layRect.LayoutRect(rect, layout.LayoutLine());
- layout = AknLayoutScalable_Avkon::scroll_handle_focus_pane(varietyIndex); // focus handle
- // The horizontal data for focus handle is missing so switch the values from the vertical data
- TAknWindowLineLayout layoutLine = layout.LayoutLine();
- if (iOrientation == CEikScrollBar::EHorizontal)
- {
- TInt height = layoutLine.iH;
- TInt width = layoutLine.iW;
- layoutLine.iW = height;
- layoutLine.iH = width;
- }
- layRect.LayoutRect(layRect.Rect(), layoutLine);
- rect = layRect.Rect(); // parent rect is now the focus handle
-
- // the retangle includes the variated length of the middle,
- // the top and bottom graphics must subtracted from the value
-
- // do not change the handle retangle, the full size is needed in drawing
- // set the width or height to be correct
- if (iOrientation == CEikScrollBar::EVertical)
- {
- iHandleRect.iTl.iX = rect.iTl.iX;
- iHandleRect.iBr.iX = rect.iBr.iX;
- }
- else
- {
- iHandleRect.iTl.iY = rect.iTl.iY;
- iHandleRect.iBr.iY = rect.iBr.iY;
- }
-
-
- }
TInt CAknDoubleSpanScrollIndicator::GetCurrentThumbSpanInPixels()
{
@@ -868,261 +764,15 @@
return iHandleHighlight;
}
-void CAknDoubleSpanScrollIndicator::SetTouchAreaControl( CCoeControl* aTouchAreaControl )
- {
- iTouchAreaControl = aTouchAreaControl;
- }
-
+
void CAknDoubleSpanScrollIndicator::SetBackgroudHighlight( TBool aBackgroudHighlight )
{
// This does nothing in non-touch
iBackgroundHighlight = aBackgroudHighlight;
-
}
TBool CAknDoubleSpanScrollIndicator::BackgroudHighlight() const
{
return iBackgroundHighlight;
}
-CFbsBitmap* CAknDoubleSpanScrollIndicator::CopyAndApplyEffectL(
- const CFbsBitmap* aSource, TBool aCopyOnly )
- {
- CFbsBitmap* newBitmap = NULL;
-
-
- newBitmap = new ( ELeave ) CFbsBitmap;
-
-
-
- TInt err = newBitmap->Create( aSource->SizeInPixels(), aSource->DisplayMode() );
-
- // We still have to return a dummy bitmap object, even if
- // the creation fails.
- if ( err == KErrNone )
- {
- SEpocBitmapHeader header = aSource->Header();
-
- // We support only 16-bit (5-6-5), since this is the default
- // display mode icons are created in. Otherwise just copy.
- if ( !aCopyOnly && aSource->DisplayMode() == EColor64K )
- {
- // Don't modify header data.
- TInt size = ( header.iBitmapSize - header.iStructSize ) /
- sizeof( TUint16 );
-
- aSource->BeginDataAccess();
-
- TUint16* source = (TUint16*)aSource->DataAddress();
- TUint16* dest = (TUint16*)newBitmap->DataAddress();
-
- for ( TInt i = 0; i < size; ++i )
- {
- *dest = *source++;
- TBitmapFx::PixelEffect( dest++ );
- }
-
- aSource->EndDataAccess( ETrue );
- }
- else
- {
- // This is probably faster than blitting it. Copy
- // the header data in the same run to minimize size
- // calculations, although it's already correct in the
- // new bitmap.
- TInt size = aSource->Header().iBitmapSize;
- aSource->BeginDataAccess();
-
- Mem::Copy( newBitmap->DataAddress(),
- aSource->DataAddress(),
- size );
-
- aSource->EndDataAccess( ETrue );
- }
- }
-
-
- return newBitmap;
- }
-
-
-void TBitmapFx::PixelEffect( TUint16* aPixelData )
- {
- // Note: the calculations in this function are based on
- // graphic designers' conception of what Photoshop does
- // to images with certain values. There might also be some
- // room for optimizations.
-
- TRGB rgb;
-
- rgb.iR = ( *aPixelData & 0xF800 ) >> 11;
- rgb.iG = ( *aPixelData & 0x7E0 ) >> 5;
- rgb.iB = ( *aPixelData & 0x1F );
-
- // Scale to 65280 (0xFF00). Under no circumstances should these
- // values end up being > 0xFF00 or < 0x00
- rgb.iR *= 2105.82f;
- rgb.iG *= 1036.20f;
- rgb.iB *= 2105.82f;
-
- // Convert RGB to HSL
- TInt min = Min( rgb.iR, Min( rgb.iG, rgb.iB ) );
- TInt max = Max( rgb.iR, Max( rgb.iG, rgb.iB ) );
- TInt delta = max - min;
-
- THSL hsl = { 0, 0, 0 } ;
-
- // Lightness
- hsl.iL = ( max + min ) >> 1;
-
- if ( delta == 0 )
- {
- hsl.iH = 0;
- hsl.iS = 0;
- }
- else
- {
- // Hue
- if ( max == rgb.iR )
- {
- hsl.iH = 10880 * ( rgb.iG - rgb.iB ) / delta;
- }
- else if ( max == rgb.iG )
- {
- hsl.iH = 10880 * ( rgb.iB - rgb.iR ) / delta + 21760;
- }
- else if ( max == rgb.iB )
- {
- hsl.iH = 10880 * ( rgb.iR - rgb.iG ) / delta + 43520;
- }
-
- // Saturation
- if ( hsl.iL <= 32640 )
- {
- hsl.iS = ( delta << KPrecision ) / ( ( max + min ) >> KPrecision );
- }
- else
- {
- hsl.iS = ( delta << KPrecision ) / ( ( 0x1FE00 - ( max + min ) ) >> KPrecision );
- }
- }
-
- // Apply hue shift, moved to proper range in HueToRGB()
- hsl.iH += 0x715;
-
- // Apply saturation
- // +10 in -100..100 in Photoshop terms. According to related material
- // corresponds to 0xCC0 when applied to 0x00..0xFF00
- hsl.iS += 0xCC0;
-
- if ( hsl.iS > 0xFF00 )
- {
- hsl.iS = 0xFF00;
- }
-
- // Convert back to RGB
- TInt v1;
- TInt v2;
-
- if ( hsl.iS == 0 )
- {
- rgb.iR = ( hsl.iL * 255 ) >> KPrecision;
- rgb.iG = ( hsl.iL * 255 ) >> KPrecision;
- rgb.iB = ( hsl.iL * 255 ) >> KPrecision;
- }
- else
- {
- if ( hsl.iL < 32640 )
- {
- v2 = ( hsl.iL * ( ( 0xFF00 + hsl.iS ) >> KPrecision ) ) >> KPrecision;
- }
- else
- {
- v2 = ( hsl.iL + hsl.iS ) - ( ( hsl.iS >> KPrecision ) * ( hsl.iL >> KPrecision ) );
- }
-
- v1 = 2 * hsl.iL - v2;
-
- rgb.iR = ( HueToRGB( v1, v2, hsl.iH + 0x54FF ) );
- rgb.iG = ( HueToRGB( v1, v2, hsl.iH ) );
- rgb.iB = ( HueToRGB( v1, v2, hsl.iH - 0x54FF ) );
- }
-
- rgb.iR /= 2105.82f;
- rgb.iG /= 1036.20f;
- rgb.iB /= 2105.82f;
-
- // Apply contrast.. However, the original req stated that the
- // contrast value should be +6 in a range of -100..100.
- // With 5 and 6 bit values and fixed point math such a small value has
- // no effect, so it has been left out. The code is here in case
- // the contrast value is updated at some point.
- /*
- const TInt contrast = ( 6 * 65536 / 200 ) + 65536;
-
- rgb.iR -= 15;
- rgb.iG -= 31;
- rgb.iB -= 15;
-
- rgb.iR *= contrast;
- rgb.iG *= contrast;
- rgb.iB *= contrast;
-
- rgb.iR /= 65536;
- rgb.iG /= 65536;
- rgb.iB /= 65536;
-
- rgb.iR += 15;
- rgb.iG += 31;
- rgb.iB += 15;
- */
-
- // Apply brightness, -40 in a range of -100..100 for
- // 0..255 rgb values, which corresponds to -5 for 5 bit
- // and -10 for 6 bit rgb values.
- rgb.iR -= 5;
- rgb.iG -= 10;
- rgb.iB -= 5;
-
- if ( rgb.iR < 0 ) rgb.iR = 0;
- if ( rgb.iG < 0 ) rgb.iG = 0;
- if ( rgb.iB < 0 ) rgb.iB = 0;
-
- if ( rgb.iR > 31 ) rgb.iR = 31;
- if ( rgb.iG > 63 ) rgb.iG = 63;
- if ( rgb.iB > 31 ) rgb.iB = 31;
-
- *aPixelData =
- ( rgb.iB | ( rgb.iG << 5 ) | ( rgb.iR << 11 ) );
- }
-
-TInt TBitmapFx::HueToRGB( TInt v1, TInt v2, TInt aH )
- {
- while ( aH < 0 )
- {
- aH += 0xFF00;
- }
-
- while ( aH >= 0xFF00 )
- {
- aH -= 0xFF00;
- }
-
- if ( ( ( 6 * aH ) ) < 0xFF00 )
- {
- return v1 + ( ( v2 - v1 ) * ( ( 6 * aH ) >> KPrecision ) >> KPrecision );
- }
-
- if ( ( ( 2 * aH ) ) < 0xFF00 )
- {
- return v2;
- }
-
- if ( ( ( 3 * aH ) ) < 0x1FE00 )
- {
- return v1 + ( ( v2 - v1 ) * ( ( ( 0xA9FF - aH ) * 6 ) >> KPrecision ) >> KPrecision );
- }
-
- return v1;
- }
-