idlehomescreen/nativeuicontroller/src/aisoftkeyrenderer.cpp
changeset 0 f72a12da539e
child 9 f966699dea19
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/nativeuicontroller/src/aisoftkeyrenderer.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,676 @@
+/*
+* 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();
+    }