diff -r f5050f1da672 -r 04becd199f91 javauis/lcdui_akn/lcdui/src/CMIDMenuHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/lcdui_akn/lcdui/src/CMIDMenuHandler.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,469 @@ +/* +* Copyright (c) 2003-2008 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: Menu pane handling, common across all Displayables. +* +*/ + + +// INCLUDE FILES +// CEikonEnv API for iEkonEnv : +// - to retrieving CEikAppUi +// - to obtain device screen size +#include +// API for iAppUi +#include +// API for iMenuBar +#include +#include +#include +// using constants for soft keys +#include +// mocros for avkon resources +#include +// macros for resources +#include +// API needed for iDisplayable and iDefaultDisplayable members +#include "CMIDDisplayable.h" +#include "CMIDCanvas.h" +#include "CMIDMenuHandler.h" +// CMIDTickerController API for iTickerController (stored in tls structure) +#include "CMIDTicker.h" +// for setting key decoder in tls +#include "CMIDKeyDecoder.h" +#include "lcdui.h" +#include +#include "CMIDUIManager.h" + + +const TInt KResolutionStringLength = 4; + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMIDMenuHandler* CMIDMenuHandler::NewL(MMIDEnv& aEnv) +{ + CMIDMenuHandler* self = new(ELeave) CMIDMenuHandler(aEnv); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; +} + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMIDMenuHandler::ConstructL() +{ + iAppUi = iEikEnv.EikAppUi(); + iMenuBar = new(ELeave) CEikMenuBar; + iMenuBar->ConstructL(this, 0, R_MIDP_MENUBAR_DEFAULT); + + iCba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba, + CEikButtonGroupContainer::EHorizontal, + this, + R_AVKON_SOFTKEYS_EMPTY); +#ifdef RD_JAVA_S60_RELEASE_9_2 + static_cast(iCba->ButtonGroup())->EnableItemSpecificSoftkey(EFalse); +#endif + const TSize screenSize = iEikEnv.ScreenDevice()->SizeInPixels(); + iCba->SetBoundingRect(TRect(screenSize)); + iViewRect = iAppUi->ClientRect(); + iCba->ReduceRect(iViewRect); + iAppUi->AddToStackL(iMenuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus); + SetScalingFactors(); +} + + +void CMIDMenuHandler::HideMenuIfVisible() +{ + if (iMenuBar->IsDisplayed()) + { + iMenuBar->StopDisplayingMenuBar(); + } +} + +void CMIDMenuHandler::UpdateMenuIfVisibleL() +{ + if (iMenuBar->IsDisplayed()) + { // Menu is currently displayed + + iMenuBar->StopDisplayingMenuBar(); + + ShowMenuL(iMenuType); + } +} + + +// C++ default constructor +CMIDMenuHandler::CMIDMenuHandler(MMIDEnv& aEnv) + : iEnv(aEnv) + ,iEikEnv(*(CEikonEnv::Static())) +{ +} + +// Destructor +CMIDMenuHandler::~CMIDMenuHandler() +{ + HideMenuIfVisible(); + if (iAppUi) + { + iAppUi->RemoveFromStack(iMenuBar); + } + delete iMenuBar; + delete iCba; + iMenuItems.Reset(); +} + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::ShowMenuL +// +// @see DynInitMenuPaneL() +// ----------------------------------------------------------------------------- +// +void CMIDMenuHandler::ShowMenuL(const TMenuType& aType) +{ + if (iDisplayable && aType != ENoMenu && !iAttemptingToDisplayMenu) + { + iMenuType = aType; + iDisplayable->CreateMenuItemsL(iMenuType, iMenuItems); + + // Set the CEikMenuBar type according to internal type + if (aType == EOptionsMenu) + { + iMenuBar->SetMenuType(CEikMenuBar::EMenuOptions); + } + else if (aType == EOkMenu || aType == EHelpMenu || aType == EScreenAndHelpMenu) + { + iMenuBar->SetMenuType(CEikMenuBar::EMenuContext); + } + + // If there is anything to show, open the menu + if (iMenuItems.Count() > 0 && !iMenuBar->IsDisplayed()) + { + iAttemptingToDisplayMenu = ETrue; + iMenuBar->TryDisplayMenuBarL(); + } + // Reset the menu type always to options menu just in case + iMenuBar->SetMenuType(CEikMenuBar::EMenuOptions); + } +} + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::MenuItemsCount +// +// +// ----------------------------------------------------------------------------- +// +TUint CMIDMenuHandler::MenuItemsCount() const +{ + return iMenuItems.Count(); +} + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::SetDisplayable +// +// +// ----------------------------------------------------------------------------- +// +void CMIDMenuHandler::SetDisplayable(CMIDDisplayable* aDisplayable) +{ + iDisplayable = aDisplayable; + + if (iDisplayable) + { + SendMultipleKeyPressedEvent(); + } +} +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::SendMultipleKeyPressedEventL +// +// +// ----------------------------------------------------------------------------- +// +void CMIDMenuHandler::SendMultipleKeyPressedEvent() +{ + ASSERT(iDisplayable); + + RWsSession wsSession = CCoeEnv::Static()->WsSession(); + TWsEvent event; + + // Check the current Display type if it is canvas enable the + // multiple key events, other wise disable it. + MMIDComponent* component = iDisplayable->Component(); + MMIDComponent::TType type = component->Type(); + + if (type == MMIDComponent::ECanvas) + event.SetType(EEnableMultipleKeyPressedEvent); // set event type enable multiple key pressed event + else + event.SetType(EDisableMultipleKeyPressedEvent); // set event type disable multiple key pressed event + event.SetTimeNow(); // set the event time + event.SetHandle(wsSession.WsHandle()); // set window server handle + wsSession.SendEventToAllWindowGroups(event); +} + + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::ProcessCommandL +// +// +// ----------------------------------------------------------------------------- +// +void CMIDMenuHandler::ProcessCommandL(TInt aCommandId) +{ + HideMenuIfVisible(); + + // + if (aCommandId == EAknSoftkeyExit) + { + iAppUi->HandleCommandL(EEikCmdExit); + return; + } + + if (aCommandId == EEikCmdCanceled) + { + return; + } + + if (aCommandId == EAknSoftkeyOptions) + { + ShowMenuL(EOptionsMenu); + return; + } + + if (aCommandId == EStdKeyDevice3) + { + ShowMenuL(EOkMenu); + return; + } + + if (iDisplayable) + { + iDisplayable->ProcessCommandL(aCommandId); + } +} + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::SetEmphasis +// +// +// ----------------------------------------------------------------------------- +// +void CMIDMenuHandler::SetEmphasis(CCoeControl* aMenuControl,TBool aEmphasis) +{ + if (!iDisplayable) + { + return; + } + + if (aEmphasis) + { + if (MMIDComponent::ECanvas == iDisplayable->Component()->Type()) + { + iEnv.PostMidletEvent(EBackground); + } + } + else + { + if (MMIDComponent::ECanvas == iDisplayable->Component()->Type()) + { + iEnv.PostMidletEvent(EForeground); + } + } + + iAppUi->UpdateStackedControlFlags(aMenuControl, aEmphasis? 0: ECoeStackFlagRefusesFocus, + ECoeStackFlagRefusesFocus); + iAppUi->HandleStackChanged(); +} + +// ----------------------------------------------------------------------------- +// CMIDMenuHandler::DynInitMenuPaneL +// +// +// ----------------------------------------------------------------------------- +void CMIDMenuHandler::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane) +{ + if (aResourceId == R_MIDP_MENUPANE_DISPLAYABLE) + { + TInt numItems = iMenuItems.Count(); + for (TInt i = 0; i < numItems; i++) + { + aMenuPane->AddMenuItemL(iMenuItems[i]); + } + + iAttemptingToDisplayMenu = EFalse; + } + +} + + +/** SetScalingFactors + + Sets MIDlet's original size and target size resolutions if those are defined in JAD or manifest. + If attribute is missing or it's not defined correctly, the value will be 0,0. + This value is later used as an "error value". + @param - + @return - + + */ +void CMIDMenuHandler::SetScalingFactors() +{ + TPtrC orgSize; + // If JAD attribute Nokia-MIDlet-Original-Display-Size is defined, it will be used to scale Canvas. + if (iEnv.MidletAttribute(LcduiMidletAttributes::KAttribOrigDisplaySize, orgSize) == KErrNone) + { + iOrgMIDletScrSize = DesToTSize(orgSize); + TPtrC targetSize; + // If JAD attribute Nokia-MIDlet-Original-Display-Size and Nokia-MIDlet-Target-Display-Size are defined, + // those will be used to scale Canvas. + // If Nokia-MIDlet-Target-Display-Size is invalid, Canvas will still be scaled, + // if Nokia-MIDlet-Original-Display-Size is correct. + if (iOrgMIDletScrSize.iHeight != 0 && iOrgMIDletScrSize.iWidth != 0 && + iEnv.MidletAttribute(LcduiMidletAttributes::KAttribTargetDisplaySize, + targetSize) == KErrNone) + { + iTargetMIDletScrSize = DesToTSize(targetSize); + } + + // Load Nokia-MIDlet-allow-scaling-on-orientation-switch attribute + // setting. This attribute is valid only when original MIDlet size + // is defined. + if (iOrgMIDletScrSize.iHeight != 0 && iOrgMIDletScrSize.iWidth != 0) + { + iScaleMIDletOnOrientSwitch = iEnv.MidletAttributeIsSetToVal( + LcduiMidletAttributes::KAttribAllowScalingOnOrientationSwitch, + LcduiMidletAttributeValues::KTrueValue); + } + } +} + +/** DesToTSize + + Utility to parse TPtrC to TSize. + This util is made for graphics scaling feature. + @param TPtrC + @return TSize + + */ +TSize CMIDMenuHandler::DesToTSize(TPtrC scrSize) +{ + TSize newSize; + TSize errorSize(0, 0); + TInt newIntWidth; + TInt newIntHeight; + // Assumed max. 9999 pixels in width. + TBuf newWidth; + // Assumed max. 9999 pixels in height. + TBuf newHeight; + TChar tmpChar; + _LIT(lComma, ","); + TChar comma(','); + + // The digits of width and height must be divided by comma + if (scrSize.Find(lComma) != KErrNotFound) + { + TLex16 lex(scrSize); + while (lex.Peek() != comma) + { + tmpChar = lex.Get(); + if (tmpChar.IsDigit() && newWidth.Length() < KResolutionStringLength) + { + newWidth.Append(tmpChar); + } + else if (!tmpChar.IsSpace()) + { + // If character is not digit or space + return errorSize; + } + } + lex.Get(); + while (!lex.Eos()) + { + tmpChar = lex.Get(); + if (tmpChar.IsDigit() && newHeight.Length() < KResolutionStringLength) + { + newHeight.Append(tmpChar); + } + else if (!tmpChar.IsSpace()) + { + // If character is not digit or space + return errorSize; + } + } + + // Width and height must have at least one digit each + if (newWidth.Length() > 0 && newHeight.Length() > 0) + { + TLex16 widthLex(newWidth); + widthLex.Val(newIntWidth); + TLex16 heightLex(newHeight); + heightLex.Val(newIntHeight); + newSize.SetSize(TInt(newIntWidth), TInt(newIntHeight)); + return newSize; + } + } + // If there is no comma between the digits or there is no digits in width or height + return errorSize; +} + +TSize CMIDMenuHandler::GetScreenSize() const +{ + // It get size of screen from iEikEnv's screen device. + const CEikonEnv* env = &iEikEnv; + return env->ScreenDevice()->SizeInPixels(); +} + +TBool CMIDMenuHandler::IsScalingEnabled() const +{ + //If iOrgMIDletScrSize has been initialized then scaling is on. + //It's enough to check either height or width only. + return (iOrgMIDletScrSize.iHeight != 0); +} + +TBool CMIDMenuHandler::IsScalingEffectiveInCurrentScreen() const +{ + if (IsScalingEnabled()) + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, screen); + TSize screenSize = screen.Size(); + + TSize origResolution = iOrgMIDletScrSize; + if (iScaleMIDletOnOrientSwitch) + { + // ensure that origResolution and screenSize are in portrait + origResolution = TSize(Min(iOrgMIDletScrSize.iHeight, iOrgMIDletScrSize.iWidth), + Max(iOrgMIDletScrSize.iHeight, iOrgMIDletScrSize.iWidth)); + screenSize = TSize(Min(screen.Height(), screen.Width()), + Max(screen.Height(), screen.Width())); + } + + // If origResolution and screenSize are different, then + // scaling is effective. + return (screenSize.iHeight != origResolution.iHeight || + screenSize.iWidth != origResolution.iWidth); + } + else + { + return EFalse; + } +} +// End of File