idlehomescreen/nativeuicontroller/src/aisoftkeyrenderer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:40:49 +0200
changeset 0 f72a12da539e
child 9 f966699dea19
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* 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:  Handles publishing to title pane.
*
*/


#include <eikbtgpc.h>
#include <aknappui.h>
#include <StringLoader.h>
#include <AiNativeUi.rsg>
#include <gulicon.h>
#include <AknIconUtils.h>
#include <AknsConstants.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <AknStatuspaneUtils.h>
#include <layoutmetadata.cdl.h>
#include <AknUtils.h>
#include <eiksoftkeyimage.h>
#include <AknSgcc.h>
#include <aiscutplugindomaincrkeys.h>

#include "ainativeui.hrh"
#include "aisoftkeyrenderer.h"
#include "ainativeuiplugins.h"
#include "aiscutdefs.h"


using namespace AiNativeUiController;

// Index for left softkey; defined in avkon
const TInt KNativeUiLeftSoftkeyId = 0;

// Index for right softkey; defined in avkon
const TInt KNativeUiRightSoftkeyId = 2;

const TInt KControlArrayCBAButton1Posn        =0;
const TInt KControlArrayCBAButton2Posn        =2;
const TInt KControlArrayCBAButtonMiddlePosn   =3;

const TInt KWideScreenWidth          = 640;


inline TAknWindowComponentLayout DoCompose( TAknWindowComponentLayout aLine1,
    TAknWindowComponentLayout aLine2 )
    {
    return TAknWindowComponentLayout::Compose( aLine1, aLine2 );
    }

inline TAknTextComponentLayout DoComposeText( TAknWindowComponentLayout aLine1,
    TAknTextComponentLayout aLine2 )
    {
    return TAknWindowComponentLayout::ComposeText( aLine1, aLine2 );
    }


// -----------------------------------------------------------------------------
//
// Calculate (whole) softkey area for Bottom button (landscape)
// -----------------------------------------------------------------------------
static TBool HDLayoutActive()
    {
    TInt resourceId = 0;
    CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();

    if ( statusPane ) // Return the resource ID of app statuspane if it exists.
        {
        resourceId = statusPane->CurrentLayoutResId();
        }
    else // If this app does not have statuspane, then we ask the layout from AknCapServer.
        {
        resourceId = CAknSgcClient::CurrentStatuspaneResource();
        }

    TBool retVal = EFalse;

    if ( Layout_Meta_Data::IsLandscapeOrientation() )
        {
        // Can be widescreen only in landscape orientation.
        retVal = ( resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL ||
                   resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE  ||
                   resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL_FLAT ||
                   resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT );
        }

    return retVal;
    }


// -----------------------------------------------------------------------------
//
// Calculate softkey image graphics area for Bottom button (landscape)
// -----------------------------------------------------------------------------
static TRect SoftkeyRectBottomGraphics()
    {
    TRect screen;
    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );

    TAknWindowComponentLayout rightAreaLayout(
        AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );

    TAknWindowComponentLayout bottomSKLayout(
        DoCompose( rightAreaLayout,
                   AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ) );

    // Calculate softkey rects.
    // Left (bottom in landscape) softkey layout.
    TAknLayoutRect leftSoftkeyLayoutRect;
    leftSoftkeyLayoutRect.LayoutRect( screen,
                                      bottomSKLayout.LayoutLine() );
    TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() );

    // Calculate softkey image layout.
    // Left (bottom in landscape) softkey layout.
    TAknWindowLineLayout leftSoftkeyImageLayout(
        DoCompose(
            bottomSKLayout,
            AknLayoutScalable_Avkon::sctrl_sk_bottom_pane_g1() ).LayoutLine() );


    TAknLayoutRect qgn_graf_sk_left;
    qgn_graf_sk_left.LayoutRect( screen, leftSoftkeyImageLayout );

    return qgn_graf_sk_left.Rect();
    }


// -----------------------------------------------------------------------------
//
// Calculate softkey image graphics area for Top button (landscape)
// -----------------------------------------------------------------------------
static TRect SoftkeyRectTopGraphics()
    {
    TRect screen;
    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );

    TAknWindowComponentLayout rightAreaLayout(
        AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );

    TAknWindowComponentLayout topSKLayout(
        DoCompose( rightAreaLayout,
                   AknLayoutScalable_Avkon::sctrl_sk_top_pane() ) );

    // Calculate softkey rects.
    // Right (top in landscape) softkey layout.
    TAknLayoutRect rightSoftkeyLayoutRect;
    rightSoftkeyLayoutRect.LayoutRect( screen,
                                       topSKLayout.LayoutLine() );
    TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() );

    // Left (bottom in landscape) softkey layout.
    // Right (top in landscape) softkey layout.
    TAknWindowLineLayout rightSoftkeyImageLayout(
        DoCompose(
            topSKLayout,
            AknLayoutScalable_Avkon::sctrl_sk_top_pane_g1() ).LayoutLine() );

    TAknLayoutRect qgn_graf_sk_right;
    qgn_graf_sk_right.LayoutRect( screen, rightSoftkeyImageLayout );
    return qgn_graf_sk_right.Rect();
    }


// -----------------------------------------------------------------------------
// SoftkeyRectL
// Calculate soft key rect
// -----------------------------------------------------------------------------
static TRect SoftkeyRectL( CEikButtonGroupContainer& aContainer, TInt aPos, TBool aImageOn )
    {
    TRect rect;

    if( AknStatuspaneUtils::StaconPaneActive() )
        {
        TInt variety( 0 );

        if( AknStatuspaneUtils::StaconSoftKeysLeft() )
            {
            variety = 1;
            }

        TRect parentRect( iAvkonAppUi->ApplicationRect() );

        switch( aPos )
            {
            case KControlArrayCBAButton1Posn:
                {
                TAknWindowComponentLayout layout0( AknLayoutScalable_Avkon::area_bottom_pane( 2 ) );
                TAknWindowComponentLayout layout1( AknLayoutScalable_Avkon::stacon_bottom_pane() );

                // If clock is shown in stacon, cba area is smaller.
                TInt bottomCbaVariety( variety );

                if( AknStatuspaneUtils::ExtendedStaconPaneActive() )
                    {
                    bottomCbaVariety += 2;
                    }

                TAknWindowComponentLayout layout2( AknLayoutScalable_Avkon::control_bottom_pane_stacon( bottomCbaVariety ) );

                if( aImageOn )
                    {
                    // Icon layout
                    TAknWindowComponentLayout iconLayout( AknLayoutScalable_Avkon::control_bottom_pane_stacon_g1() );

                    TAknWindowComponentLayout lskIconLayout( DoCompose( layout0,
                        DoCompose( layout1, DoCompose( layout2, iconLayout ) ) ) );

                    TAknWindowLineLayout lskIcon( lskIconLayout.LayoutLine() );

                    TAknLayoutRect qgn_icon_lsk;

                    qgn_icon_lsk.LayoutRect( parentRect, lskIcon );

                    rect = qgn_icon_lsk.Rect();
                    }
                else
                    {
                    // Text layout
                    TAknTextComponentLayout textLayout( AknLayoutScalable_Avkon::control_bottom_pane_stacon_t1( variety ) );

                    TAknTextComponentLayout lskTextLayout( DoComposeText( layout0,
                        DoComposeText( layout1, DoComposeText( layout2, textLayout ) ) ) );

                    TAknTextLineLayout lskText( lskTextLayout.LayoutLine() );

                    TAknLayoutText qgn_text_lsk;

                    qgn_text_lsk.LayoutText( parentRect, lskText );

                    rect = qgn_text_lsk.TextRect();
                    }
                }
                break;
            case KControlArrayCBAButton2Posn:
                {
                TAknWindowComponentLayout layout0( AknLayoutScalable_Avkon::area_top_pane( 2 ) );
                TAknWindowComponentLayout layout1( AknLayoutScalable_Avkon::stacon_top_pane() );

                TInt topCbaVariety( variety );

                if( AknStatuspaneUtils::ExtendedStaconPaneActive() )
                    {
                    topCbaVariety += 4;
                    }

                TAknWindowComponentLayout layout2( AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety ) );

                if( aImageOn )
                    {
                    // Icon layout
                    TAknWindowComponentLayout iconLayout( AknLayoutScalable_Avkon::control_top_pane_stacon_g1() );

                    TAknWindowComponentLayout rskIconLayout( DoCompose( layout0,
                        DoCompose( layout1, DoCompose( layout2, iconLayout ) ) ) );

                    TAknWindowLineLayout rskIcon( rskIconLayout.LayoutLine() );

                    TAknLayoutRect qgn_icon_rsk;

                    qgn_icon_rsk.LayoutRect( parentRect, rskIcon );

                    rect = qgn_icon_rsk.Rect();
                    }
                else
                    {
                    // Text layout
                    TAknTextComponentLayout textLayout( AknLayoutScalable_Avkon::control_top_pane_stacon_t1( variety ) );

                    TAknTextComponentLayout rskTextLayout( DoComposeText( layout0,
                        DoComposeText( layout1, DoComposeText( layout2, textLayout ) ) ) );

                    TAknTextLineLayout rskText( rskTextLayout.LayoutLine() );

                    TAknLayoutText qgn_text_rsk;

                    qgn_text_rsk.LayoutText( parentRect, rskText );

                    rect = qgn_text_rsk.TextRect();
                    }
                }
                break;
            default:
                User::Leave( KErrNotSupported );
                break;

            }
        }
    else
        {
        TInt textVariety( 0 );
        TInt graphVariety( 0 );

        TBool mskEnabled( AknLayoutUtils::MSKEnabled() && Layout_Meta_Data::IsMSKEnabled() );

        if ( mskEnabled )
            {
            textVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 3;
            graphVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 4;
            }
        else
            {
            textVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 0;
            graphVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 4;
            }

        CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) );

        TRect parentRect( cba->Rect() );

        switch( aPos )
            {
            case KControlArrayCBAButton1Posn:
                {
                if( aImageOn )
                    {
                    if ( HDLayoutActive() &&
                         AKN_LAYOUT_WINDOW_screen.iW == KWideScreenWidth )
                        {
                        rect = SoftkeyRectBottomGraphics();
                        }
                     else
                        {

                        TAknLayoutRect qgn_icon_lsk;

                        qgn_icon_lsk.LayoutRect( parentRect,
                            AknLayoutScalable_Avkon::control_pane_g1( graphVariety ).LayoutLine() );

                        rect = qgn_icon_lsk.Rect();
                        }
                    }
                else
                    {
                    TAknLayoutText qgn_text_lsk;

                    qgn_text_lsk.LayoutText( parentRect,
                        AknLayoutScalable_Avkon::control_pane_t1( textVariety ).LayoutLine() );

                    rect = qgn_text_lsk.TextRect();
                    }
                }
                break;
            case KControlArrayCBAButton2Posn:
                {
                if( aImageOn )
                    {
                    if ( HDLayoutActive() &&
                         AKN_LAYOUT_WINDOW_screen.iW == KWideScreenWidth )
                        {
                        rect = SoftkeyRectTopGraphics();
                        }
                     else
                        {
                        TAknLayoutRect qgn_icon_rsk;

                        qgn_icon_rsk.LayoutRect( parentRect,
                            AknLayoutScalable_Avkon::control_pane_g2( graphVariety ).LayoutLine() );

                        rect = qgn_icon_rsk.Rect();
                        }
                    }
                else
                    {
                    TAknLayoutText qgn_text_rsk;

                    qgn_text_rsk.LayoutText( parentRect,
                        AknLayoutScalable_Avkon::control_pane_t2( textVariety ).LayoutLine() );

                    rect = qgn_text_rsk.TextRect();
                    }
                }
                break;
            case KControlArrayCBAButtonMiddlePosn:
                {
                if( !mskEnabled || aImageOn )
                    {
                    // No msk, or asking image size for msk
                    User::Leave( KErrNotSupported );
                    }
                else
                    {
                    TAknLayoutText qgn_text_msk;

                    qgn_text_msk.LayoutText( parentRect,
                        AknLayoutScalable_Avkon::control_pane_t3( textVariety ).LayoutLine() );

                    rect = qgn_text_msk.TextRect();
                    }
                }
                break;
            default:
                User::Leave( KErrNotFound );
                break;
            }
        }

    return rect;
    }


// -----------------------------------------------------------------------------
// SoftkeySizeL
// Calculate soft key size
// -----------------------------------------------------------------------------
static TSize SoftkeySizeL( CEikButtonGroupContainer& aContainer, TInt aPos, TBool aImageOn )
    {
    TSize size( SoftkeyRectL( aContainer, aPos, aImageOn ).Size() );

    return size;
    }


void CAiSoftKeyRenderer::ConstructL()
    {
    // load default soft key labels from resource
    CreateDefaultSoftKeysL();
    }


CAiSoftKeyRenderer* CAiSoftKeyRenderer::NewLC()
    {
    CAiSoftKeyRenderer* self = new( ELeave ) CAiSoftKeyRenderer();
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }


CAiSoftKeyRenderer::~CAiSoftKeyRenderer()
    {
    delete iText;

    if ( iCba )
        {
        CEikCba* cba =
            static_cast< CEikCba* >( iCba->ButtonGroup() );
        iAppUi->RemoveFromStack( cba );
        }
    delete iCba;
    }


CAiSoftKeyRenderer::CAiSoftKeyRenderer()
    {
    iAppUi = iAvkonAppUi;
    }




void CAiSoftKeyRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
                                        TInt aContent,
                                        const TDesC16& aText,
                                        TInt aIndex )
    {
    if( aPlugin.PublisherInfoL()->iUid == KShortcutPluginUid )
        {
        if( aContent == KAiScutContent[EAiScutContentShortcutShortCaption].id )
            {
            HBufC* temp = aText.AllocL();
            delete iText;
            iText = temp;

            UpdateSoftKeyL( aIndex, NULL );
            }
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    }


void CAiSoftKeyRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
                                        TInt aContent,
                                        TInt aResource,
                                        TInt aIndex )
    {
    if( aPlugin.PublisherInfoL()->iUid == KShortcutPluginUid )
        {
        if( aContent == KAiScutContent[EAiScutContentShortcutShortCaption].id )
            {
            TInt internalId = KErrNotFound;
            switch( aResource )
                {
                case EAiScutResourceBackCaption:
                    {
                    internalId = R_NATIVEUI_SK_BACK;
                    break;
                    }
                case EAiScutResourceNewMsgShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_NEWMSG;
                    break;
                    }
                case EAiScutResourceNewEmailShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_EMAIL;
                    break;
                    }
                case EAiScutResourceNewSyncMLMailShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_SYNCMLMAIL;
                    break;
                    }
                case EAiScutResourceNewPostcardShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_MMSPOSTCARD;
                    break;
                    }
                case EAiScutResourceSelectMsgTypeShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_MSGTYPE;
                    break;
                    }
                case EAiScutResourceNewAudioMsgShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_AUDIOMSG;
                    break;
                    }
                case EAiScutResourceChangeThemeShortCaption:
                    {
                    internalId = R_NATIVEUI_SK_CHANGETHEME;
                    break;
                    }
                default:
                    {
                    User::Leave( KErrNotFound );
                    }
                }

            HBufC* temp = StringLoader::LoadL( internalId );
            delete iText;
            iText = temp;

            UpdateSoftKeyL( aIndex, NULL );
            }
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    }


void CAiSoftKeyRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
                                        TInt aContent,
                                        const TDesC8& aBuf,
                                        TInt aIndex )
    {
    if( aPlugin.PublisherInfoL()->iUid == KShortcutPluginUid )
        {
        if( aContent == KAiScutContent[EAiScutContentShortcutSkIcon].id )
            {
            CGulIcon* icon = NULL;
            TPckg<CGulIcon*>( icon ).Copy( aBuf );
            // icon ownership is transferred
            UpdateSoftKeyL( aIndex, icon );
            }
        else
            {
            User::Leave( KErrNotSupported );
            }
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    }


void CAiSoftKeyRenderer::CreateDefaultSoftKeysL()
    {
    // If we already have cba, then do nothing.
    if ( iCba )
        {
        return;
        }

    // Otherwise create brand new cba.
    iCba = CEikButtonGroupContainer::NewL(
        CEikButtonGroupContainer::ECba,
        CEikButtonGroupContainer::EHorizontal,
        iAppUi,
        R_NATIVEUI_SOFTKEYS_DEFAULT,
        0 ); // Does not add to stack

    iCba->SetBoundingRect( iAppUi->ApplicationRect() );

    CCoeControl* cba = iCba->ButtonGroup()->AsControl();

    static_cast<CEikCba*>(cba)->SetSkinBackgroundId(
        KAknsIIDQsnBgAreaControlIdle );

    cba->MakeVisible( ETrue );

    iAppUi->RemoveFromStack( cba ); // Well, it is not in stack
    iAppUi->AddToStackL( cba,
                    KNativeUiCbaPriority,
                    ECoeStackFlagRefusesFocus | ECoeStackFlagRefusesAllKeys );
    }


void CAiSoftKeyRenderer::UpdateSoftKeyL( TInt aKey, CGulIcon* aIcon )
    {
    if( !iCba )
        {
        iCba = iAppUi->Cba();
        }

    // remove the locked flag if any
    aKey &= KScutBitMaskLocked;

    TInt buttonPosImage;
    TInt buttonPosText;
    TInt buttonCmd;

    if( aKey == KLeftSoftkeyId )
        {
        buttonPosImage = KControlArrayCBAButton1Posn;
        buttonPosText = KNativeUiLeftSoftkeyId;
        buttonCmd = ENativeUiSoftkeyLeft;
        }
    else if(aKey == KRightSoftkeyId)
        {
        buttonPosImage = KControlArrayCBAButton2Posn;
        buttonPosText = KNativeUiRightSoftkeyId;
        buttonCmd = ENativeUiSoftkeyRight;
        }
    else
        {
        delete aIcon;
        return;
        }

    if( aIcon )
        {
        CleanupStack::PushL( aIcon );

        TSize size( SoftkeySizeL( *iCba, buttonPosImage, ETrue ) );

        AknIconUtils::SetSize( aIcon->Bitmap(), size, EAspectRatioPreserved );
        AknIconUtils::SetSize( aIcon->Mask(), size, EAspectRatioPreserved );

        CEikImage* image = new ( ELeave ) CEikImage;
        image->SetPictureOwnedExternally( EFalse );
        // Bitmap and mask ownerships are transferred
        image->SetPicture( aIcon->Bitmap(), aIcon->Mask() );
        aIcon->SetBitmapsOwnedExternally( ETrue );

        // Image ownership is transferred
        EikSoftkeyImage::SetImage( iCba, *image, aKey == KLeftSoftkeyId );

        CleanupStack::PopAndDestroy( aIcon );
        }
    else
        {
        EikSoftkeyImage::SetLabel( iCba, aKey == KLeftSoftkeyId );
        iCba->SetCommandL( buttonPosText,
                            buttonCmd,
                            *iText );
        }

    iCba->DrawDeferred();
    }