uiacceltk/hitchcock/coretoolkit/src/HuiSoftKeyControl.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiSoftKeyControl.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,433 @@
+/*
+* Copyright (c) 2006-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 of a soft key control class. CHuiSoftKeyControl 
+*                is a control that displays the soft key labels and handles 
+*                soft key input events.
+*
+*/
+
+
+
+#include "uiacceltk/HuiSoftKeyControl.h"  // Class definition
+#include "uiacceltk/HuiTextVisual.h"
+#include "uiacceltk/HuiEvent.h"
+#include "uiacceltk/HuiDisplay.h"
+#include "uiacceltk/HuiEnv.h"
+#include "uiacceltk/HuiCommand.h"
+#include "uiacceltk/HuiUtil.h"
+#include "uiacceltk/HuiAnchorLayout.h"
+#include "uiacceltk/HuiBrushes.h"
+
+const TReal32 KLabelHeightFactor = 0.1f; // Soft key label height relative to display height.
+const TReal32 KLabelWidthFactor = 0.25f; // Soft key label width relative to display width.
+const TUint KDefaultExitTransitionTime = 500; // Default exit animation transition time.
+const TUint KDefaultEnterTransitionTime = 500; // Default exit animation transition time.
+
+EXPORT_C CHuiSoftKeyControl* CHuiSoftKeyControl::NewL(CHuiEnv& aEnv)
+    {
+    CHuiSoftKeyControl* self = NewLC(aEnv);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+
+EXPORT_C CHuiSoftKeyControl* CHuiSoftKeyControl::NewLC(CHuiEnv& aEnv)
+    {
+    CHuiSoftKeyControl* self = new (ELeave) CHuiSoftKeyControl(aEnv);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+
+CHuiSoftKeyControl::CHuiSoftKeyControl(CHuiEnv& aEnv)
+        : CHuiControl(aEnv), iCurrentLocation(EHuiSkinLocationNone),
+        iExitTransitionTime(KDefaultExitTransitionTime),
+        iEnterTransitionTime(KDefaultEnterTransitionTime)
+    {
+    }
+
+
+void CHuiSoftKeyControl::ConstructL()
+    {
+    // Append anchor layout to be used to align the label visuals relatively to display
+    iLayout = (CHuiAnchorLayout*)(AppendLayoutL(EHuiLayoutTypeAnchor));
+
+    // Create left soft key label visual and align it using anchor layout
+    iLeftLabel = CHuiTextVisual::AddNewL(*this, iLayout);
+    iLeftLabel->SetAlign(EHuiAlignHLeft, EHuiAlignVBottom);
+    iLeftLabel->SetStyle(EHuiTextStyleSoftkey, EHuiBackgroundTypeDark);
+    iLeftLabel->SetPadding(TPoint(2, 3));
+
+    // Create right soft key label visual and align it using anchor layout
+    iRightLabel = CHuiTextVisual::AddNewL(*this, iLayout);
+    iRightLabel->SetAlign(EHuiAlignHRight, EHuiAlignVBottom);
+    iRightLabel->SetStyle(EHuiTextStyleSoftkey, EHuiBackgroundTypeDark);
+    iRightLabel->SetPadding(TPoint(2, 3));    
+
+    //iRightLabel->SetFlag(EHuiVisualFlagLayoutUpdateNotification);
+    iLayout->SetFlag(EHuiVisualFlagLayoutUpdateNotification);
+    }
+
+
+EXPORT_C void CHuiSoftKeyControl::SetBackgroundType(THuiBackgroundType aBackgroundType)
+    {
+    iLeftLabel->SetStyle(EHuiTextStyleSoftkey, aBackgroundType);
+    iRightLabel->SetStyle(EHuiTextStyleSoftkey, aBackgroundType);
+    }
+
+
+CHuiSoftKeyControl::~CHuiSoftKeyControl()
+    {
+    delete iLeftText;
+    delete iRightText;
+    
+    iRightLabel = NULL;
+    iRightLabelImageBrush = NULL;
+    iLayout = NULL;
+    }
+
+
+
+EXPORT_C void CHuiSoftKeyControl::SetLabelL(THuiSoftKeyPosition aKeyPos, const TDesC& aText, TBool aAnimateControl)
+    {
+    // Animate softkey label change, if a valid softkey location is set.
+    if(iCurrentLocation != EHuiSkinLocationNone)
+        {
+        if(aKeyPos == EHuiSoftKeyLower || aKeyPos == EHuiSoftKeyLeft)
+            {
+            // Exit view, animate only the changed softkey.
+            ExitView(ESoftkeyLabelLeft | (aAnimateControl ? ESoftkeyLabelRight : 0));
+            // Cache label text
+            delete iLeftText;
+            iLeftText = NULL;
+            iLeftText = aText.AllocL();
+            }
+        else
+            {
+            // Exit view, animate only the changed softkey.
+            ExitView(ESoftkeyLabelRight | (aAnimateControl ? ESoftkeyLabelLeft : 0));
+            // Cache label text
+            delete iRightText;
+            iRightText = NULL;
+            iRightText = aText.AllocL();
+            }
+
+        // Update label(s) after softkey has exited the view.
+        if(aAnimateControl)
+            {
+            Env().Send(THuiCustomEventCommand(ECustomEventUpdateLabels, this), iExitTransitionTime);
+            }
+        else
+            {
+            Env().Send(THuiCustomEventCommand(ECustomEventUpdateLabel, this), iExitTransitionTime);
+            }
+        }
+    else
+        {
+        /** @todo  Display orientation affects how the key positions are
+                   interpreted? */
+
+        if(aKeyPos == EHuiSoftKeyLower || aKeyPos == EHuiSoftKeyLeft)
+            {
+            iLeftLabel->SetTextL(aText);
+            }
+        else
+            {
+            iRightLabel->SetTextL(aText);
+            }
+        }                
+    }
+
+/**
+ * Sets background image to the softkeys.
+ */
+EXPORT_C void CHuiSoftKeyControl::SetBackgroundL(THuiImage image, TInt aLeftBorderWidth, TInt aRightBorderWidth)
+    {
+    // Create image brush for left softkey (if needed)
+    if (iLeftLabelImageBrush==NULL)
+        {
+        iLeftLabel->EnableBrushesL();
+        iLeftLabelImageBrush = CHuiImageBrush::NewL(image);
+        iLeftLabelImageBrush->SetBorders(aLeftBorderWidth, aRightBorderWidth, 0, 0);
+        iLeftLabel->Brushes()->AppendL(iLeftLabelImageBrush, EHuiHasOwnership);
+        }
+    else
+        {
+        // Set background image for the softkey
+        iLeftLabelImageBrush->SetImage(image);
+        iLeftLabelImageBrush->SetBorders(aLeftBorderWidth, aRightBorderWidth, 0, 0);
+        }
+
+    // Create image brush for right softkey (if needed)
+    if (iRightLabelImageBrush==NULL)
+        {
+        iRightLabel->EnableBrushesL();
+        iRightLabelImageBrush = CHuiImageBrush::NewL(image);
+        iRightLabelImageBrush->SetBorders(aLeftBorderWidth, aRightBorderWidth, 0, 0);
+        iRightLabel->Brushes()->AppendL(iRightLabelImageBrush, EHuiHasOwnership);
+        }
+    else
+        {
+        // Set background image for the softkey
+        iRightLabelImageBrush->SetImage(image);
+        iRightLabelImageBrush->SetBorders(aLeftBorderWidth, aRightBorderWidth, 0, 0);
+        }
+
+    }
+
+
+EXPORT_C void CHuiSoftKeyControl::SetAnimationTimes( TUint aEnterTransition, TUint aExitTransition )
+    {
+    iEnterTransitionTime = aEnterTransition;
+    iExitTransitionTime = aExitTransition;
+    }
+
+
+EXPORT_C void CHuiSoftKeyControl::EnterView(TUint aLabelMask)
+    {
+    // Show control
+    TRAP_IGNORE(ShowL( *Display() ))
+
+    // Set anchor points to target
+    SetAnchorPoints(iCurrentLocation, ETrue, aLabelMask);
+
+    // Do the transition
+    iLayout->UpdateChildrenLayout(iEnterTransitionTime);
+    }
+
+
+EXPORT_C void CHuiSoftKeyControl::ExitView(TUint aLabelMask)
+    {
+    ExitView(iCurrentLocation, aLabelMask);
+    }
+
+
+TBool CHuiSoftKeyControl::OfferEventL(const THuiEvent& aEvent)
+    {
+    if(aEvent.IsCustomEvent())
+        {
+        if(aEvent.iParam == ECustomEventEnterView)
+            {
+            // Hide soft keys first
+            SetAnchorPoints(iCurrentLocation, EFalse);
+            iLayout->UpdateChildrenLayout(0);
+
+            // Enter soft keys to view
+            EnterView();
+            return ETrue;
+            }
+        if(aEvent.iParam == ECustomEventUpdateLabels || aEvent.iParam == ECustomEventUpdateLabel)
+            {
+            if(iLeftText)
+                {
+                // Define label update mask
+                TUint labelMask = ESoftkeyLabelLeft | ((aEvent.iParam == ECustomEventUpdateLabels) ? ESoftkeyLabelRight : 0);
+
+                // Hide soft key(s) first
+                SetAnchorPoints(iCurrentLocation, EFalse, labelMask);
+                iLayout->UpdateChildrenLayout(0);
+
+                // Update label text
+                iLeftLabel->SetTextL(*iLeftText);
+                delete iLeftText;
+                iLeftText = 0;
+
+                // Enter soft key(s) to view
+                EnterView(labelMask);
+                }
+            if(iRightText)
+                {
+                // Define label update mask
+                TUint labelMask = ESoftkeyLabelRight | ((aEvent.iParam == ECustomEventUpdateLabels) ? ESoftkeyLabelLeft : 0);
+
+                // Hide soft key(s) first
+                SetAnchorPoints(iCurrentLocation, EFalse, labelMask);
+                iLayout->UpdateChildrenLayout(0);
+
+                // Update label text
+                iRightLabel->SetTextL(*iRightText);
+                delete iRightText;
+                iRightText = 0;
+
+                // Enter soft key(s) to view
+                EnterView(labelMask);
+                }
+
+            return ETrue;
+            }
+        }
+
+    return EFalse;
+    }
+
+
+void CHuiSoftKeyControl::VisualLayoutUpdated(CHuiVisual& aVisual)
+    {
+    if(&aVisual == iLayout)
+        {
+        // Get current soft keys location
+        THuiSkinLocation location = Env().Skin().Location(EHuiSkinElementSoftKeys);
+
+        if(location != iCurrentLocation)
+            {
+            // Get the previous location
+            THuiSkinLocation prevLocation = iCurrentLocation;
+
+            // Set the current location
+            iCurrentLocation = location;
+
+            // Enter from new location after exit transition is completed.
+            Env().Send(THuiCustomEventCommand(ECustomEventEnterView, this), ExitView(prevLocation));
+            }
+        }
+    }
+
+
+void CHuiSoftKeyControl::SetAnchorPoints(THuiSkinLocation aSkinLocation, TBool aShown, TUint aLabelMask)
+    {
+    // Recalculate visual rectangles depending on the skin location.
+    switch(aSkinLocation)
+        {
+        case EHuiSkinLocationTop:
+            HUI_DEBUG(_L("CHuiSoftKeyControl::ResetLabelRectangles() - EHuiSkinLocationTop not yet supported."));
+            HUI_PANIC(THuiPanic::ENotImplemented)
+            break;
+
+        case EHuiSkinLocationRight:
+            {
+            // Determine soft key label x-offset from the right border of the layout.
+            TReal32 leftX = aShown ? -KLabelWidthFactor : 0.0f;
+            TReal32 rightX = aShown ? 0.0 : KLabelWidthFactor;
+
+            if(aLabelMask & ESoftkeyLabelLeft)
+                {
+                // Define label text alignment
+                iLeftLabel->SetAlign(EHuiAlignHRight, EHuiAlignVBottom);
+
+                // Anchor top-left corner of the left soft key label (ordinal 0)
+                iLayout->SetAnchor(EHuiAnchorTopLeft, 0,
+                    EHuiAnchorOriginRight, EHuiAnchorOriginVCenter,
+                    EHuiAnchorMetricRelativeToSize, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(leftX, 0.f));
+
+                // Anchor bottom-right corner of the left soft key label (ordinal 0)
+                iLayout->SetAnchor(EHuiAnchorBottomRight, 0,
+                    EHuiAnchorOriginRight, EHuiAnchorOriginBottom,
+                    EHuiAnchorMetricRelativeToSize, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(rightX, 0.f));
+                }
+            if(aLabelMask & ESoftkeyLabelRight)
+                {
+                // Define label text alignment
+                iRightLabel->SetAlign(EHuiAlignHRight, EHuiAlignVTop);
+
+                // Anchor top-left corner of the right soft key label (ordinal 1)
+                iLayout->SetAnchor(EHuiAnchorTopLeft, 1,
+                    EHuiAnchorOriginRight, EHuiAnchorOriginTop,
+                    EHuiAnchorMetricRelativeToSize, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(leftX, 0.f));
+
+                // Anchor bottom-right corner of the right soft key label (ordinal 1)
+                iLayout->SetAnchor(EHuiAnchorBottomRight, 1,
+                    EHuiAnchorOriginRight, EHuiAnchorOriginVCenter,
+                    EHuiAnchorMetricRelativeToSize, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(rightX, 0.f));
+                }
+            
+            break;
+            }
+        case EHuiSkinLocationBottom:
+            {
+            // Determine soft key label y-offset from the bottom of the layout.
+            TReal32 topY = aShown ? -KLabelHeightFactor : 0.0f;
+            TReal32 bottomY = aShown ? 0.0 : KLabelHeightFactor;
+
+            if(aLabelMask & ESoftkeyLabelLeft)
+                {
+                // Define label text alignment
+                iLeftLabel->SetAlign(EHuiAlignHLeft, EHuiAlignVBottom);
+                
+                // Retrieve text label visual width.
+                /// @todo There should be a way to transform this width to relative coordinates
+                /// otherwise we can't make sure that the text label is wide enough.
+                TSize leftSize = iLeftLabel->TextExtents();
+
+                // Anchor top-left corner of the left soft key label (ordinal 0)
+                iLayout->SetAnchor(EHuiAnchorTopLeft, 0,
+                    EHuiAnchorOriginLeft, EHuiAnchorOriginBottom,
+                    EHuiAnchorMetricRelativeToSize, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(0.f, topY));
+
+                // Anchor bottom-right corner of the left soft key label (ordinal 0)
+                iLayout->SetAnchor(EHuiAnchorBottomRight, 0,
+                    EHuiAnchorOriginLeft, EHuiAnchorOriginBottom,
+                    EHuiAnchorMetricAbsolute, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(leftSize.iWidth, bottomY));
+                }
+
+            if(aLabelMask & ESoftkeyLabelRight)
+                {
+                // Define label text alignment
+                iRightLabel->SetAlign(EHuiAlignHRight, EHuiAlignVBottom);
+
+                // Retrieve text label visual width.
+                /// @todo There should be a way to transform this width to relative coordinates
+                /// otherwise we can't make sure that the text label is wide enough.
+                TSize rightSize = iRightLabel->TextExtents();
+
+                // Anchor top-left corner of the right soft key label (ordinal 1)
+                iLayout->SetAnchor(EHuiAnchorTopLeft, 1,
+                    EHuiAnchorOriginRight, EHuiAnchorOriginBottom,
+                    EHuiAnchorMetricAbsolute, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(-rightSize.iWidth, topY));
+
+                // Anchor bottom-right corner of the right soft key label (ordinal 1)
+                iLayout->SetAnchor(EHuiAnchorBottomRight, 1,
+                    EHuiAnchorOriginRight, EHuiAnchorOriginBottom,
+                    EHuiAnchorMetricRelativeToSize, EHuiAnchorMetricRelativeToSize,
+                    THuiTimedPoint(0.f, bottomY));
+                }
+
+            break;
+            }
+        case EHuiSkinLocationLeft:
+            HUI_DEBUG(_L("CHuiSoftKeyControl::ResetLabelRectangles() - EHuiSkinLocationLeft not yet supported."));
+            HUI_PANIC(THuiPanic::ENotImplemented)
+            break;
+
+        default:
+            HUI_DEBUG(_L("CHuiSoftKeyControl::ResetLabelRectangles() - Unknown soft key draw location."));
+            HUI_PANIC(THuiPanic::ENotImplemented)
+            break;
+        }
+    }
+
+
+TUint CHuiSoftKeyControl::ExitView(THuiSkinLocation aTarget, TUint aLabelMask)
+    {
+    // Bail out if target location is none.
+    if(aTarget == EHuiSkinLocationNone)
+        {
+        return 0;
+        }
+
+    // Set anchor points to target
+    SetAnchorPoints(aTarget, EFalse, aLabelMask);
+
+    // Do the transition
+    iLayout->UpdateChildrenLayout(iExitTransitionTime);
+
+    return iExitTransitionTime;
+    }