diff -r aecbbf00d063 -r d48ab3b357f1 uifw/EikStd/coctlsrc/AknDoubleSpanScrollIndicator.cpp --- 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 #include #include -// 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; - } -