javauis/lcdui_akn/lcdui/src/CMIDMenuHandler.cpp
branchRCL_3
changeset 26 2455ef1f5bbc
equal deleted inserted replaced
25:ae942d28ec0e 26:2455ef1f5bbc
       
     1 /*
       
     2 * Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Menu pane handling, common across all Displayables.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 // CEikonEnv API for iEkonEnv :
       
    21 // - to retrieving CEikAppUi
       
    22 // - to obtain device screen size
       
    23 #include <eikenv.h>
       
    24 // API for iAppUi
       
    25 #include <eikappui.h>
       
    26 // API for iMenuBar
       
    27 #include <eikmenub.h>
       
    28 #include <e32cmn.h>
       
    29 #include <AknUtils.h>
       
    30 // using constants for soft keys
       
    31 #include <avkon.hrh>
       
    32 // mocros for avkon resources
       
    33 #include <avkon.rsg>
       
    34 // macros for resources
       
    35 #include <lcdui.rsg>
       
    36 // API needed for iDisplayable and iDefaultDisplayable members
       
    37 #include "CMIDDisplayable.h"
       
    38 #include "CMIDCanvas.h"
       
    39 #include "CMIDMenuHandler.h"
       
    40 // CMIDTickerController API for iTickerController (stored in tls structure)
       
    41 #include "CMIDTicker.h"
       
    42 // for setting key decoder in tls
       
    43 #include "CMIDKeyDecoder.h"
       
    44 #include "lcdui.h"
       
    45 #include <j2me/jdebug.h>
       
    46 #include "CMIDUIManager.h"
       
    47 #include "coreuiavkonlcdui.h"
       
    48 #include "coreuiappui.h"
       
    49 
       
    50 
       
    51 const TInt KResolutionStringLength = 4;
       
    52 
       
    53 // ============================ MEMBER FUNCTIONS ===============================
       
    54 
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CMIDMenuHandler::NewL
       
    58 // Two-phased constructor.
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 CMIDMenuHandler* CMIDMenuHandler::NewL(MMIDEnv& aEnv)
       
    62 {
       
    63     CMIDMenuHandler* self = new(ELeave) CMIDMenuHandler(aEnv);
       
    64     CleanupStack::PushL(self);
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop(self);
       
    67 
       
    68     return self;
       
    69 }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CMIDMenuHandler::ConstructL
       
    73 // Symbian 2nd phase constructor can leave.
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 void CMIDMenuHandler::ConstructL()
       
    77 {
       
    78     iAppUi = iEikEnv.EikAppUi();
       
    79     iMenuBar = new(ELeave) CEikMenuBar;
       
    80     iMenuBar->ConstructL(this, 0, R_MIDP_MENUBAR_DEFAULT);
       
    81 
       
    82     iCba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba,
       
    83                                           CEikButtonGroupContainer::EHorizontal,
       
    84                                           this,
       
    85                                           R_AVKON_SOFTKEYS_EMPTY);
       
    86 #ifdef RD_JAVA_S60_RELEASE_9_2
       
    87     static_cast<CEikCba*>(iCba->ButtonGroup())->EnableItemSpecificSoftkey(EFalse);
       
    88 #endif
       
    89     const TSize screenSize = iEikEnv.ScreenDevice()->SizeInPixels();
       
    90     iCba->SetBoundingRect(TRect(screenSize));
       
    91     iViewRect = iAppUi->ClientRect();
       
    92     iCba->ReduceRect(iViewRect);
       
    93     iAppUi->AddToStackL(iMenuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus);
       
    94     SetScalingFactors();
       
    95 }
       
    96 
       
    97 
       
    98 void CMIDMenuHandler::HideMenuIfVisible()
       
    99 {
       
   100     if (iMenuBar->IsDisplayed())
       
   101     {
       
   102         iMenuBar->StopDisplayingMenuBar();
       
   103     }
       
   104 }
       
   105 
       
   106 void CMIDMenuHandler::UpdateMenuIfVisibleL()
       
   107 {
       
   108     if (iMenuBar->IsDisplayed())
       
   109     { // Menu is currently displayed
       
   110 
       
   111         iMenuBar->StopDisplayingMenuBar();
       
   112 
       
   113         ShowMenuL(iMenuType);
       
   114     }
       
   115 }
       
   116 
       
   117 
       
   118 // C++ default constructor
       
   119 CMIDMenuHandler::CMIDMenuHandler(MMIDEnv& aEnv)
       
   120         : iEnv(aEnv)
       
   121         ,iEikEnv(*(CEikonEnv::Static()))
       
   122 {
       
   123 }
       
   124 
       
   125 // Destructor
       
   126 CMIDMenuHandler::~CMIDMenuHandler()
       
   127 {
       
   128     HideMenuIfVisible();
       
   129     if (iAppUi)
       
   130     {
       
   131         iAppUi->RemoveFromStack(iMenuBar);
       
   132     }
       
   133     delete iMenuBar;
       
   134     delete iCba;
       
   135     iMenuItems.Reset();
       
   136 }
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // CMIDMenuHandler::ShowMenuL
       
   140 //
       
   141 // @see DynInitMenuPaneL()
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 void CMIDMenuHandler::ShowMenuL(const TMenuType& aType)
       
   145 {
       
   146     if (iDisplayable && aType != ENoMenu && !iAttemptingToDisplayMenu)
       
   147     {
       
   148         iMenuType = aType;
       
   149         iDisplayable->CreateMenuItemsL(iMenuType, iMenuItems);
       
   150 
       
   151         // Set the CEikMenuBar type according to internal type
       
   152         if (aType == EOptionsMenu)
       
   153         {
       
   154             iMenuBar->SetMenuType(CEikMenuBar::EMenuOptions);
       
   155         }
       
   156         else if (aType == EOkMenu || aType == EHelpMenu || aType == EScreenAndHelpMenu)
       
   157         {
       
   158             iMenuBar->SetMenuType(CEikMenuBar::EMenuContext);
       
   159         }
       
   160 
       
   161         // If there is anything to show, open the menu
       
   162         if (iMenuItems.Count() > 0 && !iMenuBar->IsDisplayed())
       
   163         {
       
   164             iAttemptingToDisplayMenu = ETrue;
       
   165             iMenuBar->TryDisplayMenuBarL();
       
   166         }
       
   167         // Reset the menu type always to options menu just in case
       
   168         iMenuBar->SetMenuType(CEikMenuBar::EMenuOptions);
       
   169     }
       
   170 }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CMIDMenuHandler::MenuItemsCount
       
   174 //
       
   175 //
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 TUint CMIDMenuHandler::MenuItemsCount() const
       
   179 {
       
   180     return iMenuItems.Count();
       
   181 }
       
   182 
       
   183 // -----------------------------------------------------------------------------
       
   184 // CMIDMenuHandler::SetDisplayable
       
   185 //
       
   186 //
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 void CMIDMenuHandler::SetDisplayable(CMIDDisplayable* aDisplayable)
       
   190 {
       
   191     iDisplayable = aDisplayable;
       
   192 
       
   193     if (iDisplayable)
       
   194     {
       
   195         SendMultipleKeyPressedEvent();
       
   196     }
       
   197 }
       
   198 // -----------------------------------------------------------------------------
       
   199 // CMIDMenuHandler::SendMultipleKeyPressedEventL
       
   200 //
       
   201 //
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 void CMIDMenuHandler::SendMultipleKeyPressedEvent()
       
   205 {
       
   206     ASSERT(iDisplayable);    
       
   207     java::ui::CoreUiAvkonAppUi* appUi =
       
   208         java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi();
       
   209     if (appUi)
       
   210     {
       
   211         MMIDComponent* component = iDisplayable->Component();
       
   212         if (component)
       
   213         {
       
   214             if (component->Type() == MMIDComponent::ECanvas)
       
   215             {
       
   216                 appUi->glueSetKeyBlockMode(ENoKeyBlock);
       
   217             }
       
   218             else
       
   219             {
       
   220                 appUi->glueSetKeyBlockMode(EDefaultBlockMode);
       
   221             }
       
   222         }
       
   223     }
       
   224 }
       
   225 
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CMIDMenuHandler::ProcessCommandL
       
   229 //
       
   230 //
       
   231 // -----------------------------------------------------------------------------
       
   232 //
       
   233 void CMIDMenuHandler::ProcessCommandL(TInt aCommandId)
       
   234 {
       
   235     HideMenuIfVisible();
       
   236 
       
   237     //
       
   238     if (aCommandId == EAknSoftkeyExit)
       
   239     {
       
   240         iAppUi->HandleCommandL(EEikCmdExit);
       
   241         return;
       
   242     }
       
   243 
       
   244     if (aCommandId == EEikCmdCanceled)
       
   245     {
       
   246         return;
       
   247     }
       
   248 
       
   249     if (aCommandId == EAknSoftkeyOptions)
       
   250     {
       
   251         ShowMenuL(EOptionsMenu);
       
   252         return;
       
   253     }
       
   254 
       
   255     if (aCommandId == EStdKeyDevice3)
       
   256     {
       
   257         ShowMenuL(EOkMenu);
       
   258         return;
       
   259     }
       
   260 
       
   261     if (iDisplayable)
       
   262     {
       
   263         iDisplayable->ProcessCommandL(aCommandId);
       
   264     }
       
   265 }
       
   266 
       
   267 // -----------------------------------------------------------------------------
       
   268 // CMIDMenuHandler::SetEmphasis
       
   269 //
       
   270 //
       
   271 // -----------------------------------------------------------------------------
       
   272 //
       
   273 void CMIDMenuHandler::SetEmphasis(CCoeControl* aMenuControl,TBool aEmphasis)
       
   274 {
       
   275     if (!iDisplayable)
       
   276     {
       
   277         return;
       
   278     }
       
   279 
       
   280     if (aEmphasis)
       
   281     {
       
   282         if (MMIDComponent::ECanvas == iDisplayable->Component()->Type())
       
   283         {
       
   284             iEnv.PostMidletEvent(EBackground);
       
   285         }
       
   286     }
       
   287     else
       
   288     {
       
   289         if (MMIDComponent::ECanvas == iDisplayable->Component()->Type())
       
   290         {
       
   291             iEnv.PostMidletEvent(EForeground);
       
   292         }
       
   293     }
       
   294 
       
   295     iAppUi->UpdateStackedControlFlags(aMenuControl, aEmphasis? 0: ECoeStackFlagRefusesFocus,
       
   296                                       ECoeStackFlagRefusesFocus);
       
   297     iAppUi->HandleStackChanged();
       
   298 }
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CMIDMenuHandler::DynInitMenuPaneL
       
   302 //
       
   303 //
       
   304 // -----------------------------------------------------------------------------
       
   305 void CMIDMenuHandler::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
       
   306 {
       
   307     if (aResourceId == R_MIDP_MENUPANE_DISPLAYABLE)
       
   308     {
       
   309         TInt numItems = iMenuItems.Count();
       
   310         for (TInt i = 0; i < numItems; i++)
       
   311         {
       
   312             aMenuPane->AddMenuItemL(iMenuItems[i]);
       
   313         }
       
   314 
       
   315         iAttemptingToDisplayMenu = EFalse;
       
   316     }
       
   317 
       
   318 }
       
   319 
       
   320 
       
   321 /** SetScalingFactors
       
   322 
       
   323  Sets MIDlet's original size and target size resolutions if those are defined in JAD or manifest.
       
   324  If attribute is missing or it's not defined correctly, the value will be 0,0.
       
   325  This value is later used as an "error value".
       
   326  @param -
       
   327  @return -
       
   328 
       
   329  */
       
   330 void CMIDMenuHandler::SetScalingFactors()
       
   331 {
       
   332     TPtrC orgSize;
       
   333     // If JAD attribute Nokia-MIDlet-Original-Display-Size is defined, it will be used to scale Canvas.
       
   334     if (iEnv.MidletAttribute(LcduiMidletAttributes::KAttribOrigDisplaySize, orgSize) == KErrNone)
       
   335     {
       
   336         iOrgMIDletScrSize = DesToTSize(orgSize);
       
   337         TPtrC targetSize;
       
   338         // If JAD attribute Nokia-MIDlet-Original-Display-Size and Nokia-MIDlet-Target-Display-Size are defined,
       
   339         // those will be used to scale Canvas.
       
   340         // If Nokia-MIDlet-Target-Display-Size is invalid, Canvas will still be scaled,
       
   341         // if Nokia-MIDlet-Original-Display-Size is correct.
       
   342         if (iOrgMIDletScrSize.iHeight != 0 && iOrgMIDletScrSize.iWidth != 0 &&
       
   343                 iEnv.MidletAttribute(LcduiMidletAttributes::KAttribTargetDisplaySize,
       
   344                                      targetSize) == KErrNone)
       
   345         {
       
   346             iTargetMIDletScrSize = DesToTSize(targetSize);
       
   347         }
       
   348 
       
   349         // Load Nokia-MIDlet-allow-scaling-on-orientation-switch attribute
       
   350         // setting. This attribute is valid only when original MIDlet size
       
   351         // is defined.
       
   352         if (iOrgMIDletScrSize.iHeight != 0 && iOrgMIDletScrSize.iWidth != 0)
       
   353         {
       
   354             iScaleMIDletOnOrientSwitch = iEnv.MidletAttributeIsSetToVal(
       
   355                                              LcduiMidletAttributes::KAttribAllowScalingOnOrientationSwitch,
       
   356                                              LcduiMidletAttributeValues::KTrueValue);
       
   357         }
       
   358     }
       
   359 }
       
   360 
       
   361 /** DesToTSize
       
   362 
       
   363  Utility to parse TPtrC to TSize.
       
   364  This util is made for graphics scaling feature.
       
   365  @param TPtrC
       
   366  @return TSize
       
   367 
       
   368  */
       
   369 TSize CMIDMenuHandler::DesToTSize(TPtrC scrSize)
       
   370 {
       
   371     TSize newSize;
       
   372     TSize errorSize(0, 0);
       
   373     TInt newIntWidth;
       
   374     TInt newIntHeight;
       
   375     // Assumed max. 9999 pixels in width.
       
   376     TBuf<KResolutionStringLength> newWidth;
       
   377     // Assumed max. 9999 pixels in height.
       
   378     TBuf<KResolutionStringLength> newHeight;
       
   379     TChar tmpChar;
       
   380     _LIT(lComma, ",");
       
   381     TChar comma(',');
       
   382 
       
   383     // The digits of width and height must be divided by comma
       
   384     if (scrSize.Find(lComma) != KErrNotFound)
       
   385     {
       
   386         TLex16 lex(scrSize);
       
   387         while (lex.Peek() != comma)
       
   388         {
       
   389             tmpChar = lex.Get();
       
   390             if (tmpChar.IsDigit() && newWidth.Length() < KResolutionStringLength)
       
   391             {
       
   392                 newWidth.Append(tmpChar);
       
   393             }
       
   394             else if (!tmpChar.IsSpace())
       
   395             {
       
   396                 // If character is not digit or space
       
   397                 return errorSize;
       
   398             }
       
   399         }
       
   400         lex.Get();
       
   401         while (!lex.Eos())
       
   402         {
       
   403             tmpChar = lex.Get();
       
   404             if (tmpChar.IsDigit() && newHeight.Length() < KResolutionStringLength)
       
   405             {
       
   406                 newHeight.Append(tmpChar);
       
   407             }
       
   408             else if (!tmpChar.IsSpace())
       
   409             {
       
   410                 // If character is not digit or space
       
   411                 return errorSize;
       
   412             }
       
   413         }
       
   414 
       
   415         // Width and height must have at least one digit each
       
   416         if (newWidth.Length() > 0 && newHeight.Length() > 0)
       
   417         {
       
   418             TLex16 widthLex(newWidth);
       
   419             widthLex.Val(newIntWidth);
       
   420             TLex16 heightLex(newHeight);
       
   421             heightLex.Val(newIntHeight);
       
   422             newSize.SetSize(TInt(newIntWidth), TInt(newIntHeight));
       
   423             return newSize;
       
   424         }
       
   425     }
       
   426     // If there is no comma between the digits or there is no digits in width or height
       
   427     return errorSize;
       
   428 }
       
   429 
       
   430 TSize CMIDMenuHandler::GetScreenSize() const
       
   431 {
       
   432     // It get size of screen from iEikEnv's screen device.
       
   433     const CEikonEnv* env = &iEikEnv;
       
   434     return env->ScreenDevice()->SizeInPixels();
       
   435 }
       
   436 
       
   437 TBool CMIDMenuHandler::IsScalingEnabled() const
       
   438 {
       
   439     //If iOrgMIDletScrSize has been initialized then scaling is on.
       
   440     //It's enough to check either height or width only.
       
   441     return (iOrgMIDletScrSize.iHeight != 0);
       
   442 }
       
   443 
       
   444 TBool CMIDMenuHandler::IsScalingEffectiveInCurrentScreen() const
       
   445 {
       
   446     if (IsScalingEnabled())
       
   447     {
       
   448         TRect screen;
       
   449         AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, screen);
       
   450         TSize screenSize = screen.Size();
       
   451 
       
   452         TSize origResolution = iOrgMIDletScrSize;
       
   453         if (iScaleMIDletOnOrientSwitch)
       
   454         {
       
   455             // ensure that origResolution and screenSize are in portrait
       
   456             origResolution = TSize(Min(iOrgMIDletScrSize.iHeight, iOrgMIDletScrSize.iWidth),
       
   457                                    Max(iOrgMIDletScrSize.iHeight, iOrgMIDletScrSize.iWidth));
       
   458             screenSize = TSize(Min(screen.Height(), screen.Width()),
       
   459                                Max(screen.Height(), screen.Width()));
       
   460         }
       
   461 
       
   462         // If origResolution and screenSize are different, then
       
   463         // scaling is effective.
       
   464         return (screenSize.iHeight != origResolution.iHeight ||
       
   465                 screenSize.iWidth != origResolution.iWidth);
       
   466     }
       
   467     else
       
   468     {
       
   469         return EFalse;
       
   470     }
       
   471 }
       
   472 // End of File