66
|
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
|