textinput/peninputarc/src/peninputlayoutcontrol/peninputpopupbubble.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 15 Sep 2010 12:34:44 +0300
branchRCL_3
changeset 50 5a1685599b76
permissions -rw-r--r--
Revision: 201035 Kit: 201036

/*
* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0""
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Implementation for CPopupBubbleCtrl
*
*/


#include <AknIconUtils.h>
#include <AknsUtils.h>
#include <AknUtils.h>
#include <AknsDrawUtils.h> 

#include "peninputpopupbubble.h"
#include "peninputlayout.h"
#include <peninputpluginutils.h>
#include <imageconversion.h> 
#include "peninputcmd.h"

const TInt KShrinkSize = 10;
const TInt KDefaultTextColorIndex = EAknsCIQsnTextColorsCG60;
const TInt KAlpha = 200;

// ======== MEMBER FUNCTIONS ========

/*****************************************************************************/
// Implementation of Class CPopupBubbleWnd

// ---------------------------------------------------------------------------
// c++ constructor
// ---------------------------------------------------------------------------
//
CPopupBubbleWnd::CPopupBubbleWnd(CPopupBubbleCtrl& aParent)
: iParent(aParent),
iSupportTransparent(EFalse)
    {
    }

// ---------------------------------------------------------------------------
// c++ destructor
// ---------------------------------------------------------------------------
//
CPopupBubbleWnd::~CPopupBubbleWnd()
    {
    //delete bitmaps    
    iBitGc.ResetAndDestroy();
    iDevice.ResetAndDestroy();
    iBitmap.ResetAndDestroy();       
    }

// ---------------------------------------------------------------------------
// Symbian constructor
// ---------------------------------------------------------------------------
//
CPopupBubbleWnd* CPopupBubbleWnd::NewL(const TRect& aRect, CPopupBubbleCtrl& aParent)
    {
    CPopupBubbleWnd* self = CPopupBubbleWnd::NewLC(aRect, aParent);
    CleanupStack::Pop(); // self;
    return self;
    }

// ---------------------------------------------------------------------------
// Symbian constructor
// ---------------------------------------------------------------------------
//
CPopupBubbleWnd* CPopupBubbleWnd::NewLC(const TRect& aRect, CPopupBubbleCtrl& aParent)
    {
    CPopupBubbleWnd* self = new ( ELeave ) CPopupBubbleWnd(aParent);
    CleanupStack::PushL( self );
    self->ConstructL(aRect);
    return self;
    }

// ---------------------------------------------------------------------------
// Symbian second-phase constructor
// ---------------------------------------------------------------------------
//
void CPopupBubbleWnd::ConstructL(const TRect& aRect)
    {
    RWindowGroup& wg = CCoeEnv::Static()->RootWin();
    CreateWindowL( wg );
    SetComponentsToInheritVisibility();
    Window().SetRequiredDisplayMode( EColor16MA );
    TInt err = Window().SetTransparencyAlphaChannel();
    iSupportTransparent = ( KErrNone == err );
    Window().SetBackgroundColor( TRgb(0,0,0,0) );

    //create bitmaps
    for(TInt i = 0; i<ELastItem; i++)
        {
        CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); // Bitmap
        CleanupStack::PushL(bitmap);
        iBitmap.AppendL(bitmap); //take ownership
        CleanupStack::Pop(bitmap);
        iBitmap[i]->Create(aRect.Size(), EColor16MA);
        
        CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(iBitmap[i]); //BitmapDevice
        CleanupStack::PushL(device);
        iDevice.AppendL(device); //take ownership
        CleanupStack::Pop(device);
        
        CFbsBitGc* bitgc = CFbsBitGc::NewL(); // GraphicsContext
        CleanupStack::PushL(bitgc);
        iBitGc.AppendL(bitgc); //take ownership
        CleanupStack::Pop(bitgc);
        }
    
    MakeVisible( ETrue );    
    SetRect(aRect);
    ActivateL();
    }

// ---------------------------------------------------------------------------
// Draw this control
// ---------------------------------------------------------------------------
//
void CPopupBubbleWnd::Draw(const TRect& aRect) const
    {    
    if ( !iParent.AbleToDraw() )
        {
        return;
        }
    
    CWindowGc& gc = SystemGc();

    if ( !SupportTransparent() )
        {
        gc.Clear( aRect ); 
        }    
    
    DrawTransparentBackground( aRect );

    if ( iParent.iForgroundBmp )
        {
        TRect innerRect = aRect;
        innerRect.Shrink( KShrinkSize, 0 );
        
        TRect iconRect;
        iconRect.iTl = TPoint( innerRect.iTl.iX + iParent.iIconOffset.iWidth, 
                innerRect.iTl.iY + iParent.iIconOffset.iHeight );
        iconRect.SetWidth( iParent.iIconSize.iWidth );
        iconRect.SetHeight( iParent.iIconSize.iHeight );
        
        if( iParent.iForgroundBmp->SizeInPixels() != iconRect.Size() )
            {
            AknIconUtils::SetSize( iParent.iForgroundBmp, iconRect.Size(), EAspectRatioNotPreserved );
            }
            
        TRect srcRect( TPoint( 0, 0 ), iParent.iForgroundBmp->SizeInPixels() );
        
        if( iParent.iForgroundBmpMask )
            {
            if( iParent.iForgroundBmpMask->SizeInPixels() != iconRect.Size() )
                {
                AknIconUtils::SetSize( iParent.iForgroundBmpMask, iconRect.Size(), EAspectRatioNotPreserved);
                }
                        
            gc.SetBrushStyle( CGraphicsContext::ENullBrush );
            gc.BitBltMasked( iconRect.iTl, 
                              iParent.iForgroundBmp, 
                              srcRect,
                              iParent.iForgroundBmpMask,
                              EFalse);
            }
        else
            {
            gc.BitBlt( iconRect.iTl,
                        iParent.iForgroundBmp,
                        srcRect );
            }            
        }
    
    if ( iParent.iText && iParent.iText->Length() > 0 )
        {
        gc.SetBrushStyle( CGraphicsContext::ENullBrush );
        TAknLayoutText textLayout;
        textLayout.LayoutText(Rect(), iParent.iTextFormat);
        TRgb color( KRgbBlack );  // sane default for nonskinned case
        if ( AknsUtils::AvkonSkinEnabled() )
            {
            AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
                                   color, KAknsIIDQsnTextColors, iParent.iTextColorIndex );
            }
         textLayout.DrawText(gc, *(iParent.iText), ETrue, color);
        }    
    }

// ---------------------------------------------------------------------------
// Resize this control
// ---------------------------------------------------------------------------
//
void CPopupBubbleWnd::SizeChanged()
    {
    TRect rect = Rect();        
    
    iRect[EMiddleItem] = rect;    
    
    iRect[EMiddleItem].Shrink( KShrinkSize, 0 );
      
    // horizon
    if( rect.iTl.iY == iRect[EMiddleItem].iTl.iY && rect.iBr.iY == iRect[EMiddleItem].iBr.iY )
        {
        iRect[ELeftItem] = TRect( rect.iTl, TPoint( iRect[EMiddleItem].iTl.iX, iRect[EMiddleItem].iBr.iY ) );
        iRect[ERightItem] = TRect( TPoint( iRect[EMiddleItem].iBr.iX, iRect[EMiddleItem].iTl.iY), rect.iBr );    
        }
    else if( rect.iTl.iX == iRect[EMiddleItem].iTl.iX &&  rect.iBr.iX == iRect[EMiddleItem].iBr.iX )
        {
        iRect[ELeftItem] = TRect( rect.iTl, TPoint( iRect[EMiddleItem].iBr.iX, iRect[EMiddleItem].iTl.iY ) );
        iRect[ERightItem] = TRect( TPoint( iRect[EMiddleItem].iTl.iX, iRect[EMiddleItem].iBr.iY), rect.iBr );            
        }     
    
    SizeImage( iParent.iFirstBmpId, iRect[ELeftItem], iBitmap[ELeftItem], iDevice[ELeftItem], iBitGc[ELeftItem] );
    SizeImage( iParent.iMiddleBmpId, iRect[EMiddleItem], iBitmap[EMiddleItem], iDevice[EMiddleItem], iBitGc[EMiddleItem] );
    SizeImage( iParent.iLastBmpId, iRect[ERightItem], iBitmap[ERightItem], iDevice[ERightItem], iBitGc[ERightItem] );
    }

// ---------------------------------------------------------------------------
// Handle resource change
// ---------------------------------------------------------------------------
//
void CPopupBubbleWnd::HandleResourceChange( TInt aType )
    {
    if ( aType == KAknsMessageSkinChange )
        {
        // When skin changes, we need to update local bitmaps
        SizeChanged();
        }
    }

// ---------------------------------------------------------------------------
// Size images used for drawing
// ---------------------------------------------------------------------------
//
void CPopupBubbleWnd::SizeImage( TAknsItemID aId, TRect aRect, CFbsBitmap* aBitmap, CFbsBitmapDevice* aDevice, CFbsBitGc* aBitGc )
    {     
    MAknsSkinInstance* instance = AknsUtils::SkinInstance();
    TAknsItemType type = instance->GetCachedItemData( aId )->Type();
    if ( type == EAknsITMaskedBitmap )
        {
        CAknsMaskedBitmapItemData* itemData =
                static_cast<CAknsMaskedBitmapItemData*> ( instance->GetCachedItemData( aId ) );

        AknIconUtils::SetSize( itemData->Bitmap(), aRect.Size(), EAspectRatioNotPreserved );
        AknIconUtils::SetSize( itemData->Mask(), aRect.Size(), EAspectRatioNotPreserved );

        TDisplayMode bitmapmode = itemData->Bitmap()->DisplayMode();
        TDisplayMode maskmode = itemData->Mask()->DisplayMode();

        aBitmap->Resize( aRect.Size() );
        aDevice->Resize( aRect.Size() );
        aBitGc->Activate( aDevice );

        TRect entireImage( TPoint(0, 0), itemData->Bitmap()->SizeInPixels() );
        if (itemData->Mask())
            {
            aBitGc->BitBltMasked( TPoint(0, 0), itemData->Bitmap(), entireImage,
                    itemData->Mask(), ETrue );
            }
        else
            {
            aBitGc->BitBlt( TPoint(0, 0), itemData->Bitmap() );
            }

        TInt size = aBitmap->DataSize();
        TUint32* data = aBitmap->DataAddress();
        TDisplayMode mode = aBitmap->DisplayMode();

        iBitmap[ETempItem]->Resize( aRect.Size() );
        iDevice[ETempItem]->Resize( aRect.Size() );
        iBitGc[ETempItem]->Activate( iDevice[ETempItem] );
        iBitGc[ETempItem]->BitBlt( TPoint(0, 0), itemData->Mask() );
        
        TUint32* mask_data = iBitmap[ETempItem]->DataAddress(); 
         
         if (mode == EColor16MA)
             {
             for (TInt i = 0; i < size/sizeof( TUint32 ); i++)
                 {
                 TRgb colour;
                 colour.SetInternal( *(mask_data + i) );
                 if (colour != TRgb( 0x00, 0x00, 0x00, 0xFF ))
                     {
                     colour.SetInternal( *(data + i) );
                     colour.SetAlpha( KAlpha ); //semi transparent
                     *(data + i) = colour.Internal();
                     }
                 else
                     {
                     colour.SetInternal( *(data + i) );
                     colour.SetAlpha( 0x00 ); //fully transparent
                     *(data + i) = colour.Internal();                   
                     }
                 }           
             }
        }
    } 

// ---------------------------------------------------------------------------
// Draw transparent background
// ---------------------------------------------------------------------------
//

void CPopupBubbleWnd::DrawTransparentBackground( const TRect& aRect ) const
{
    CWindowGc& gc = SystemGc();

    for( TInt i=0; i<ELastItem; i++ )
        {
        if ( i == ETempItem )//skip temporary bitmap
            {
            continue;
            }
        if ( iBitmap[i] )//draw other bitmaps
            {
            gc.BitBlt( iRect[i].iTl, iBitmap[i] );
            }
        }
}

/*****************************************************************************/
// Implementation of Class CPopupBubbleCtrl

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::NewL
// Symbian constructor
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//               
EXPORT_C CPopupBubbleCtrl* CPopupBubbleCtrl::NewL( const TRect& aRect,
                               CFepUiLayout* aUiLayout,
                               TInt aCtrlId )
    {
    CPopupBubbleCtrl* ctrl = new (ELeave)CPopupBubbleCtrl( aRect,aUiLayout,aCtrlId );
    CleanupStack::PushL( ctrl );
    ctrl->BaseConstructL();
    
    CleanupStack::Pop( ctrl );
    return ctrl;
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::CPopupBubbleCtrl
// C++  constructor
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CPopupBubbleCtrl::CPopupBubbleCtrl( const TRect& aRect,
                         CFepUiLayout* aUiLayout,
                         TInt aCtrlId )
    :CFepUiBaseCtrl( aRect,aUiLayout,aCtrlId ),
     iTextColorIndex( KDefaultTextColorIndex )
    {
    SetControlType( ECtrlButton );
    SetHidenFlag( ETrue );
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::CPopupBubbleCtrl
// C++  destructor
// ---------------------------------------------------------------------------
//
EXPORT_C CPopupBubbleCtrl::~CPopupBubbleCtrl()
    {
    if ( iText )
        {
        delete iText;
        iText = NULL;
        }      
    if( iForgroundBmp )
        {
        delete iForgroundBmp;
        iForgroundBmp = NULL;
        }
    if( iForgroundBmpMask )
        {
        delete iForgroundBmpMask;
        iForgroundBmpMask = NULL;
        }        
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::SetBitmapParamL
// Set bitmap parameters used fot this bubble
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CPopupBubbleCtrl::SetBitmapParamL(
                                    CFbsBitmap* aBmpId,
                                    CFbsBitmap* aMaskBmpId,     
                                 TAknsItemID aFirstBmpId,
                                 TAknsItemID aMiddleBmpId,
                                 TAknsItemID aLastBmpId)
    {
    if( iForgroundBmp )
        {
        delete iForgroundBmp;
        iForgroundBmp = NULL;
        }
    if( iForgroundBmpMask )
        {
        delete iForgroundBmpMask;
        iForgroundBmpMask = NULL;
        }    
        
    iForgroundBmp = aBmpId;
    iForgroundBmpMask = aMaskBmpId;
    
    iFirstBmpId = aFirstBmpId;
    iMiddleBmpId =  aMiddleBmpId;
    iLastBmpId = aLastBmpId;
    
    delete iWndControl;
    iWndControl = NULL;
    iWndControl = CPopupBubbleWnd::NewL( Rect(), *this );
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::Hide
// Hide bubble control
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CPopupBubbleCtrl::Hide( TBool aFlag )
    {
    if ( iWndControl )
        {
        iWndControl->MakeVisible( !aFlag );
        }
    CFepUiBaseCtrl::Hide( aFlag );    
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::Draw
// Draw bubble control
// ---------------------------------------------------------------------------
//
EXPORT_C void CPopupBubbleCtrl::Draw()
    {
    if( !AbleToDraw() )
        {
        return;
        }    
    
    if( iWndControl )
        {
        iWndControl->DrawDeferred();
        }
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::Move
// Move bubble control
// ---------------------------------------------------------------------------
//
EXPORT_C void CPopupBubbleCtrl::Move( const TPoint& aOffset )
    {
    //leave empty
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::SetTextFormat
// Set text format used for text drawing
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CPopupBubbleCtrl::SetTextFormat( TAknTextLineLayout aTextFormat )
    {
    iTextFormat = aTextFormat;                
    }

// ---------------------------------------------------------------------------
// CPopupBubbleCtrl::SetTextL
// Set bubble text
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CPopupBubbleCtrl::SetTextL( const TDesC& aText )
    {
    delete iText;
    iText = NULL;
    iText = aText.AllocL();
    }