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