|
1 /* |
|
2 * Copyright (c) 2002-2009 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: Implementation of EIKON Menu Pane class (options menu). |
|
15 * |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 |
|
20 #include <eikmenup.h> |
|
21 #include <eikmenub.h> |
|
22 #include <eikmobs.h> |
|
23 #include <eikon.hrh> |
|
24 #include <eikpanic.h> |
|
25 #include <coemain.h> |
|
26 #include <basched.h> |
|
27 #include <barsread.h> |
|
28 #include <eikhkeyt.h> |
|
29 #include <eikbutb.h> |
|
30 #include <eikenv.h> |
|
31 #include <eikcoctl.rsg> |
|
32 #include <gulcolor.h> |
|
33 #include <gulutil.h> |
|
34 #include <eikappui.h> |
|
35 #include <eiksbfrm.h> |
|
36 #include <eikscrlb.h> |
|
37 #include <gulicon.h> |
|
38 #include <aknborders.h> // AKNLAF |
|
39 #include <aknenv.h> |
|
40 #include <AknUtils.h> |
|
41 #include <aknpopuplayout.h> |
|
42 #include <bidi.h> // Bidirectional support |
|
43 #include <bidivisual.h> |
|
44 #include <aknconsts.h> |
|
45 #include <avkon.mbg> |
|
46 #include <AknsDrawUtils.h> |
|
47 #include <AknsFrameBackgroundControlContext.h> |
|
48 #include <AknBidiTextUtils.h> |
|
49 #include <AknMarqueeControl.h> |
|
50 #include <skinlayout.cdl.h> |
|
51 #include <aknlayoutscalable_avkon.cdl.h> |
|
52 #include <AknLayoutFont.h> |
|
53 |
|
54 #include <AknsUtils.h> |
|
55 #include <AknIconUtils.h> |
|
56 #include <aknappui.h> |
|
57 |
|
58 #include <AknsEffectAnim.h> |
|
59 #include <systemwarninglevels.hrh> |
|
60 #include <layoutmetadata.cdl.h> |
|
61 #include <AknStatuspaneUtils.h> |
|
62 #include <aknCharMap.h> |
|
63 #include <gfxtranseffect/gfxtranseffect.h> //For transition effects |
|
64 #include <akntranseffect.h> //For transition effects |
|
65 #include <akntransitionutils.h> // SetAllParents method |
|
66 #include <featmgr.h> |
|
67 #include <hal.h> |
|
68 #include <avkondomainpskeys.h> |
|
69 #include <e32property.h> |
|
70 |
|
71 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
72 #include <aknlistboxtfxinternal.h> // LISTBOX EFFECTS IMPLEMENTATION |
|
73 #include <aknlistloadertfx.h> |
|
74 #include <aknlistboxtfx.h> |
|
75 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
76 |
|
77 #include <touchfeedback.h> |
|
78 #include <AknTasHook.h> |
|
79 #include <aknphysics.h> |
|
80 #include <aknphysicsobserveriface.h> |
|
81 #include <aknPriv.hrh> |
|
82 #include "aknitemactionmenudata.h" |
|
83 #include "akntrace.h" |
|
84 |
|
85 // CONSTANTS |
|
86 const TInt KItemGranularity = 4; |
|
87 const TInt KAlternativeSubmenuWidths = 5; // five alternative widths for submenus depending on max text width |
|
88 const TInt KNoSelectedRadioButtonItem = -1; |
|
89 |
|
90 // Delay before opening sub menu when dragging, 0.3s |
|
91 const TInt KCascadeMenuOpenDelay = 300000; |
|
92 |
|
93 class CRedirectionListener; |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // TaskSwapCallBack |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 TInt TaskSwapCallBack( TAny* ) |
|
100 { |
|
101 CEikonEnv::Static()->DisplayTaskList(); |
|
102 return EFalse; |
|
103 } |
|
104 |
|
105 // ============================================================================= |
|
106 // Extension class declaration & definition |
|
107 // ============================================================================= |
|
108 /* |
|
109 * CEikMenuPaneExtension |
|
110 * |
|
111 * Structure containing extra local private data members. |
|
112 * Created to preserve BC. The CEikMenuPane class contains a pointer to this structure |
|
113 * CEikmenuPane is responsible for data members of this class. |
|
114 * |
|
115 * Extension now contains menu/submenu highlight animation functionality. |
|
116 */ |
|
117 NONSHARABLE_CLASS( CEikMenuPaneExtension ): |
|
118 public CActive, |
|
119 public MCoeForegroundObserver, |
|
120 public MAknsEffectAnimObserver, |
|
121 public MCoeControlObserver, |
|
122 public MAknPhysicsObserver |
|
123 { |
|
124 public: |
|
125 enum TFlag |
|
126 { |
|
127 /** |
|
128 * If set, animation creation is attempted. If not set, animation will |
|
129 * never be created. |
|
130 */ |
|
131 EFlagUseAnimation = 0 |
|
132 }; |
|
133 |
|
134 enum TScreen |
|
135 { |
|
136 EQhdHeight = 360, |
|
137 EQhdWidth = 640 |
|
138 }; |
|
139 |
|
140 CEikMenuPaneExtension(); |
|
141 ~CEikMenuPaneExtension(); |
|
142 |
|
143 void ConstructL( CEikMenuPane* aControl ); |
|
144 void CreateAnimation(); |
|
145 void NoAnimIfError( TInt aError ); |
|
146 void UseNoAnimation(); |
|
147 void FocusGained(); |
|
148 void FocusLost(); |
|
149 |
|
150 void HandleLayoutSwitch(); |
|
151 void ChangeHighlightBackground(); |
|
152 void MenuClosed(); |
|
153 |
|
154 void ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId ); |
|
155 void ConstructMenuSctRowFromDialogL( TDes& aSpecialChars, TInt aResourceId ); |
|
156 |
|
157 void StartCascadeMenuTimerL(); |
|
158 void StopCascadeMenuTimer(); |
|
159 static TInt CascadeMenuTimerCallBack( TAny* aThis ); |
|
160 TBool IsCascadeMenuTimerActive(); |
|
161 |
|
162 void StartHighlightTimerL(); |
|
163 void ResetPressedHighlight(); |
|
164 static TInt HighlightTimerCallBack( TAny* aThis ); |
|
165 TBool HighlightTimerActive() const; |
|
166 |
|
167 void ChangePosition( TPointerEvent& aPointerEvent ); |
|
168 void CalculateParentEvent( const TPointerEvent& aPointerEvent, |
|
169 TPointerEvent& aParentEvent ); |
|
170 TRect GetBackgroundRect( const TRect& aWindowRect ) const; |
|
171 static void AdjustPopupLayoutData( TAknWindowLineLayout& aListScrollPaneLayout ); |
|
172 |
|
173 const TAknLayoutText GetMenuItemTextLayout(const TRect& aItemRect, TBool cascade); |
|
174 |
|
175 public: // Implementation of MCoeForegroundObserver |
|
176 void HandleGainingForeground(); |
|
177 void HandleLosingForeground(); |
|
178 |
|
179 public: // Implementation of MAknsEffectAnimObserver |
|
180 void AnimFrameReady( TInt aError, TInt ); |
|
181 void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType); |
|
182 |
|
183 protected: // CActive overloads |
|
184 void DoCancel(); |
|
185 void RunL(); |
|
186 |
|
187 private: // New internal methods |
|
188 void Play(); |
|
189 TBool DrawHighlightBackground( CFbsBitGc& aGc ); |
|
190 void PostDeleteAnimation(); |
|
191 void CreateAnimationL( const TSize& aHighlightSize ); |
|
192 void DoResizeL( const TSize& aHighlightSize, TBool aAboutToStart ); |
|
193 public: |
|
194 void ImmediateFeedback( TTouchLogicalFeedback aType, |
|
195 TTouchFeedbackType aFbType ); |
|
196 |
|
197 public: |
|
198 void StartCascadeMenuAppearTransition(); |
|
199 |
|
200 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
201 void CalcItemSize( MAknListBoxTfxInternal* transApi ) const; |
|
202 #endif |
|
203 |
|
204 /** |
|
205 * Prepares cascade menu for item specific commands. |
|
206 */ |
|
207 void PrepareCascadeForItemCommands(); |
|
208 |
|
209 /** |
|
210 * Returns ETrue if this menu pane belongs to a CS menu. |
|
211 * |
|
212 * @return ETrue if this menu pane belongs to a CS menu. |
|
213 */ |
|
214 TBool ContextSensitiveMenu() const; |
|
215 |
|
216 /** |
|
217 * Returns ETrue if item is item specific command and the command is not |
|
218 * dimmed. |
|
219 * |
|
220 * @param aItem Menu pane item. |
|
221 * @return ETrue if item is item specific command. |
|
222 */ |
|
223 static TBool ItemSpecificCommand( CEikMenuPaneItem& aItem ); |
|
224 |
|
225 /** |
|
226 * Enables or disables highlight |
|
227 * |
|
228 * @param aEnabled ETrue to enable highlight, EFalse to disable. |
|
229 * @param aPointerEnabled ETrue if highlight was enabled due |
|
230 * to a pointer event. |
|
231 */ |
|
232 void EnableHighlight( TBool aEnabled, TBool aPointerEnabled = EFalse ); |
|
233 |
|
234 /** |
|
235 * Is highlight enabled |
|
236 * |
|
237 * @return ETrue if highlight is enabled |
|
238 */ |
|
239 TBool HighlightEnabled(); |
|
240 |
|
241 /** |
|
242 * Sets the default highlight to options menu |
|
243 * |
|
244 */ |
|
245 void SetDefaultHighlight(); |
|
246 |
|
247 public: // Data |
|
248 TBool iHasIcon; |
|
249 TBool iIsPenEnable; |
|
250 CFbsBitmap* iCascadeBitmap; |
|
251 CFbsBitmap* iCascadeBitmapMask; |
|
252 CAknsFrameBackgroundControlContext* iBgContext; |
|
253 TInt iSubMenuWidthIndex; // index for submenu layout which depends on the text length |
|
254 CFbsBitmap* iCheckMarkBitmap; // bitmap to be drawn if the item has check box set on |
|
255 CFbsBitmap* iCheckMarkBitmapMask; // mask for the above bitmap |
|
256 CFbsBitmap* iRadioButtonBitmap; // bitmap to be drawn if the item has radio button set on |
|
257 CFbsBitmap* iRadioButtonBitmapMask; // mask for the above bitmap |
|
258 TBool iHasRadioGroup; // is ETrue if submenu contains radio button group. |
|
259 TInt iSelectedRadioButtonItem; // index of the radio button item which is currently selected (one must be selected) |
|
260 CCoeControl* iGrabbingCBAComponent; // component control of CBA which is currently grabbing the pointer |
|
261 CEikMenuPane* iControl; |
|
262 CAknsEffectAnim* iAnimation; |
|
263 /** |
|
264 * Stored flags are explained in enumeration TFlags. |
|
265 */ |
|
266 TBitFlags32 iAnimFlags; |
|
267 |
|
268 CAknCharMap* iSct; // Menu SCT row, created only when needed. |
|
269 TBool iSctHighlighted; // No "normal" menu item can be highlighted if ETrue |
|
270 |
|
271 // Pen event related flag indicating whether the (sub)menu pane has |
|
272 // already consumed EButton1Down or not. If false, |
|
273 // EButton1Up will do nothing. |
|
274 TBool iItemsReadyForPenSelection; |
|
275 TBool iSpecialCharPointed; |
|
276 // transition demarcation rectangle for cascaded submenu |
|
277 // needs to be mutable since we need to get information from Draw methods |
|
278 // (that are declared const) |
|
279 mutable TRect iCascadeDRect; |
|
280 TBool iTransitionsOn; // Transitions FtMgr flag on |
|
281 TBool iShowCascadeTransition; |
|
282 // For later deletion of cascade menu, this allows the transition system |
|
283 // to correctly handle the aborted transitions |
|
284 CEikMenuPane* iCascadeMenuObject; |
|
285 TBool iDraggedOutside; |
|
286 TPointerEvent iLastPointerEvent; |
|
287 |
|
288 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
289 CWindowGc* iGc; |
|
290 #endif |
|
291 TInt iItemsThatFitInView; |
|
292 TRect iScrollBarRect; |
|
293 TRect iSctRect; |
|
294 TInt iTotalNumberOfItemsInView; // this value includes partial items |
|
295 |
|
296 |
|
297 CIdle* iTaskSwapIdle; |
|
298 CRedirectionListener* iRedirectionListener; |
|
299 TRect iSBRect; |
|
300 RWindow* iMenuPaneWindow; // Not own, used by SCT |
|
301 TBool iLaunchCascadeMenu; |
|
302 TBool isUpdateScrollDirectly; |
|
303 TBool iPressedDown; // ETrue if pointer is down, otherwise. |
|
304 |
|
305 CEikCba* iCba; // Embedded cba |
|
306 TRect iMenuPaneRect; // Menu area of options menu |
|
307 TBool iDownOnMenuArea; // Down event received inside menu area |
|
308 TBool iDownOnCbaArea; // Down event received inside embedded CBA area |
|
309 |
|
310 /** |
|
311 * Menu pane extension flags definition. |
|
312 */ |
|
313 enum TCEikMenuPaneExtensionFlags |
|
314 { |
|
315 ESingleClickEnabled, |
|
316 EHideItemSpecificCommands, |
|
317 EContextSensitive, |
|
318 EHighlightEnabled |
|
319 }; |
|
320 |
|
321 /** |
|
322 * Menu pane extension flags. |
|
323 */ |
|
324 TBitFlags iFlags; |
|
325 |
|
326 private: // Data |
|
327 CPeriodic* iTimer; // timer to launch submenu, own |
|
328 CPeriodic* iHighlightTimer; // Timer to adjust pressed down highlight |
|
329 TInt iVerticalOffset; // Panning offset |
|
330 |
|
331 public: // MAknPhysicsObserver |
|
332 virtual void ViewPositionChanged( const TPoint& aNewPosition, |
|
333 TBool aDrawNow = ETrue, |
|
334 TUint aFlags = 0 ); |
|
335 virtual void PhysicEmulationEnded(); |
|
336 virtual TPoint ViewPosition() const; |
|
337 |
|
338 public: |
|
339 void InitPhysicsL(); |
|
340 void DoOffset( TInt aOffset ); |
|
341 void RestoreOffset( TInt aKeyCode ); |
|
342 void SetOffset( TInt aOffset ); |
|
343 inline TInt Offset() const { return iVerticalOffset; }; |
|
344 |
|
345 CAknPhysics *iPhysics; |
|
346 TPoint iViewPosition; // Current view position |
|
347 |
|
348 TInt iListTopIndex; |
|
349 TInt iListBottomIndex; |
|
350 |
|
351 TInt iViewHeight; |
|
352 TBool iFlickActive; |
|
353 TBool iPanningActive; |
|
354 TBool iKeyEventActive; |
|
355 |
|
356 // For dragging |
|
357 TPoint iStartPoint; |
|
358 TTime iStartTime; |
|
359 TPoint iPrevPoint; |
|
360 |
|
361 // For highlight |
|
362 TInt iButtonDownItem; // Item on which down event came |
|
363 TInt iNextHighlightItem; // Item waiting for highlight timer |
|
364 // When doing a full redraw drawitem should not |
|
365 // draw the background because draw has already |
|
366 // drawn it. |
|
367 TBool iFullRedraw; |
|
368 MTouchFeedback* iFeedback; |
|
369 // The top item index is stored to this member and used for controlling |
|
370 // tactile feedback when panning/flicking (feedback is only given when |
|
371 // new item comes into view, i.e. when the top item index changes) |
|
372 TInt iLastFeedbackTopItemIndex; |
|
373 }; |
|
374 |
|
375 // |
|
376 // CEikMenuPane::CMenuScroller |
|
377 // |
|
378 |
|
379 class CEikMenuPane::CMenuScroller : public CBase, public MEikScrollBarObserver |
|
380 { |
|
381 private: |
|
382 friend class CEikMenuPaneExtension; |
|
383 public: |
|
384 static CMenuScroller* NewL( CEikMenuPane& aMenu ); |
|
385 ~CMenuScroller(); |
|
386 |
|
387 inline TInt TopItemIndex() const; |
|
388 inline void SetTopItemIndex( TInt aIndex ); |
|
389 inline CIdle* Idle() const; |
|
390 public: // from MEikScrollBarObserver |
|
391 void HandleScrollEventL( CEikScrollBar* aScrollBar, TEikScrollEvent aEventType ); |
|
392 private: |
|
393 CMenuScroller( CEikMenuPane& aMenu ); |
|
394 void ConstructL(); |
|
395 private: |
|
396 CEikMenuPane& iMenuPane; |
|
397 TInt iTopItemIndex; |
|
398 CIdle* iIdle; |
|
399 }; |
|
400 |
|
401 // ----------------------------------------------------------------------------- |
|
402 // CEikMenuPane::CMenuScroller::NewL |
|
403 // ----------------------------------------------------------------------------- |
|
404 // |
|
405 CEikMenuPane::CMenuScroller* CEikMenuPane::CMenuScroller::NewL( CEikMenuPane& aMenuPane ) |
|
406 { // static |
|
407 CMenuScroller* self = new(ELeave)CMenuScroller( aMenuPane ); |
|
408 CleanupStack::PushL(self); |
|
409 self->ConstructL(); |
|
410 CleanupStack::Pop(); |
|
411 return self; |
|
412 } |
|
413 |
|
414 // ----------------------------------------------------------------------------- |
|
415 // CEikMenuPane::CMenuScroller::~CMenuScroller |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 CEikMenuPane::CMenuScroller::~CMenuScroller() |
|
419 { |
|
420 delete iIdle; |
|
421 } |
|
422 |
|
423 // ----------------------------------------------------------------------------- |
|
424 // CEikMenuPane::CMenuScroller::CMenuScroller |
|
425 // ----------------------------------------------------------------------------- |
|
426 // |
|
427 CEikMenuPane::CMenuScroller::CMenuScroller( CEikMenuPane& aMenuPane ) |
|
428 : iMenuPane( aMenuPane ), iTopItemIndex( 0 ) |
|
429 {} |
|
430 |
|
431 // ----------------------------------------------------------------------------- |
|
432 // CEikMenuPane::CMenuScroller::ConstructL |
|
433 // ----------------------------------------------------------------------------- |
|
434 // |
|
435 void CEikMenuPane::CMenuScroller::ConstructL() |
|
436 { |
|
437 iIdle = CIdle::NewL( CActive::EPriorityIdle ); |
|
438 } |
|
439 |
|
440 // ----------------------------------------------------------------------------- |
|
441 // CEikMenuPane::CMenuScroller::HandleScrollEventL |
|
442 // ----------------------------------------------------------------------------- |
|
443 // |
|
444 void CEikMenuPane::CMenuScroller::HandleScrollEventL( CEikScrollBar* aScrollBar, |
|
445 TEikScrollEvent aEventType ) |
|
446 { |
|
447 iMenuPane.HandleScrollEventL( aScrollBar, aEventType ); |
|
448 } |
|
449 |
|
450 inline TInt CEikMenuPane::CMenuScroller::TopItemIndex() const |
|
451 { return iTopItemIndex; } |
|
452 |
|
453 inline void CEikMenuPane::CMenuScroller::SetTopItemIndex(TInt aIndex) |
|
454 { |
|
455 iTopItemIndex=aIndex; |
|
456 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
457 if ( iMenuPane.iExtension ) |
|
458 { |
|
459 iTopItemIndex = aIndex; |
|
460 } |
|
461 #endif |
|
462 } |
|
463 |
|
464 inline CIdle* CEikMenuPane::CMenuScroller::Idle() const |
|
465 { return iIdle; } |
|
466 |
|
467 |
|
468 void CEikMenuPaneExtension::InitPhysicsL() |
|
469 { |
|
470 _AKNTRACE_FUNC_ENTER; |
|
471 |
|
472 iVerticalOffset = 0; |
|
473 iListTopIndex = 0; |
|
474 iLastFeedbackTopItemIndex = 0; |
|
475 iPressedDown = EFalse; |
|
476 iFlickActive = EFalse; |
|
477 |
|
478 TRect rect; |
|
479 if ( !iControl->iOwner ) |
|
480 { |
|
481 rect = iMenuPaneRect; |
|
482 } |
|
483 else |
|
484 { |
|
485 rect = iControl->Rect(); |
|
486 } |
|
487 |
|
488 TInt itemHeight = iControl->iItemHeight; |
|
489 TInt itemsInRect = rect.Height() / itemHeight; |
|
490 TInt totalItemHeight = iControl->TotalItemHeight(); |
|
491 |
|
492 iViewHeight = itemsInRect * itemHeight; |
|
493 |
|
494 TSize totalSize( rect.Width(), totalItemHeight ); |
|
495 TSize viewSize( rect.Width(), iViewHeight ); |
|
496 |
|
497 // Using main menu width also for submenu(s), this |
|
498 // enables consistent scroll physics between main |
|
499 // menu and submenus |
|
500 if ( iControl->iOwner ) |
|
501 { |
|
502 CEikMenuPane* menu = iControl->iOwner; |
|
503 |
|
504 // Go through sub menu hierarchy. There might be |
|
505 // multiple submenus, although default case is |
|
506 // only one submenu. |
|
507 while ( menu->iOwner ) |
|
508 { |
|
509 CEikMenuPane* prevMenu( menu ); |
|
510 menu = menu->iOwner; |
|
511 |
|
512 // This prevents infinite loop if iOwner is equal to menu. |
|
513 if ( menu == prevMenu ) |
|
514 { |
|
515 break; |
|
516 } |
|
517 } |
|
518 |
|
519 totalSize = TSize( menu->Rect().Width(), totalItemHeight ); |
|
520 viewSize = TSize( menu->Rect().Width(), iViewHeight ); |
|
521 } |
|
522 |
|
523 iPhysics->InitPhysicsL( totalSize, viewSize, EFalse ); |
|
524 |
|
525 iViewPosition = TPoint( rect.Width() / 2, iListTopIndex + iViewHeight / 2 ); |
|
526 _AKNTRACE( "totalSize(%d, %d)", totalSize.iWidth, totalSize.iHeight ); |
|
527 _AKNTRACE( "viewSize(%d, %d)", viewSize.iWidth, viewSize.iHeight ); |
|
528 _AKNTRACE( "iViewPosition(%d, %d)", iViewPosition.iX, iViewPosition.iY ); |
|
529 _AKNTRACE_FUNC_EXIT; |
|
530 } |
|
531 |
|
532 |
|
533 // --------------------------------------------------------------------------- |
|
534 // Physics emulation has moved the view. |
|
535 // --------------------------------------------------------------------------- |
|
536 // |
|
537 void CEikMenuPaneExtension::ViewPositionChanged( const TPoint& aNewPosition, |
|
538 TBool aDrawNow, |
|
539 TUint /*aFlags*/ ) |
|
540 { |
|
541 _AKNTRACE_FUNC_ENTER; |
|
542 if ( !iControl->iItemArray ) |
|
543 { |
|
544 return; |
|
545 } |
|
546 |
|
547 iListTopIndex = aNewPosition.iY - iViewHeight / 2; |
|
548 |
|
549 iListBottomIndex = aNewPosition.iY + iViewHeight - iViewHeight / 2; |
|
550 |
|
551 TInt delta = iViewPosition.iY - aNewPosition.iY; |
|
552 |
|
553 DoOffset( delta ); |
|
554 |
|
555 iViewPosition = aNewPosition; |
|
556 _AKNTRACE( "iListTopIndex = %d", iListTopIndex ); |
|
557 _AKNTRACE( "iListBottomIndex = %d", iListBottomIndex ); |
|
558 _AKNTRACE( "delta = %d", delta ); |
|
559 _AKNTRACE( "iViewPosition(%d,%d)", iViewPosition.iX, iViewPosition.iY ); |
|
560 |
|
561 if ( aDrawNow ) |
|
562 { |
|
563 TRAP_IGNORE( iControl->DoUpdateScrollBarL() ); |
|
564 |
|
565 if ( iControl->iOwner ) // Submenu |
|
566 { |
|
567 iControl->DrawNow(); |
|
568 } |
|
569 else |
|
570 { |
|
571 iControl->DrawNow( TRect( iMenuPaneRect.Size() ) ); |
|
572 } |
|
573 } |
|
574 _AKNTRACE_FUNC_EXIT; |
|
575 } |
|
576 |
|
577 |
|
578 void CEikMenuPaneExtension::DoOffset( TInt aOffset ) |
|
579 { |
|
580 _AKNTRACE_FUNC_ENTER; |
|
581 TInt itemsInRect = iControl->NumberOfItemsThatFitInView(); |
|
582 TInt bottomListPosition = 0; |
|
583 |
|
584 if(iControl->iItemArray->Count() > itemsInRect) |
|
585 { |
|
586 bottomListPosition = (iControl->iItemArray->Count() - itemsInRect) * iControl->iItemHeight; |
|
587 } |
|
588 |
|
589 TInt itemIndex = iListTopIndex; |
|
590 |
|
591 if ( iListTopIndex <= 0 ) |
|
592 { |
|
593 itemIndex = 0; |
|
594 } |
|
595 |
|
596 else if ( iListTopIndex >= bottomListPosition ) |
|
597 { |
|
598 itemIndex = bottomListPosition; |
|
599 } |
|
600 |
|
601 // Calculate new top item index |
|
602 TInt newTopItemIndex = itemIndex / iControl->iItemHeight; |
|
603 |
|
604 // Calculate panning offset |
|
605 SetOffset( newTopItemIndex * iControl->iItemHeight - iListTopIndex ); |
|
606 |
|
607 _AKNTRACE( " iVerticalOffset = %d", iVerticalOffset ); |
|
608 if ( newTopItemIndex >= 0 && newTopItemIndex < iControl->iItemArray->Count() ) |
|
609 { |
|
610 _AKNTRACE( "%s", "iControl->iScroller->SetTopItemIndex(newTopItemIndex);" ); |
|
611 iControl->iScroller->SetTopItemIndex(newTopItemIndex); |
|
612 } |
|
613 // calculate new top item index and offset |
|
614 TInt menuTopItemIndex = iListTopIndex/iControl->iItemHeight; |
|
615 |
|
616 TInt listBottomLimit = iControl->iItemArray->Count()* iControl->iItemHeight; |
|
617 |
|
618 if ( menuTopItemIndex > iControl->iItemArray->Count() ) |
|
619 { |
|
620 menuTopItemIndex = iControl->iItemArray->Count() - 1; |
|
621 } |
|
622 |
|
623 if ( menuTopItemIndex != iLastFeedbackTopItemIndex ) |
|
624 { |
|
625 iLastFeedbackTopItemIndex = menuTopItemIndex; |
|
626 // If the top list item index has changed, that means that there's |
|
627 // a new list item in view and thus feedback needs to be given |
|
628 // in case there's flicking or panning ongoing and not doing |
|
629 // bounce action |
|
630 if ( iFlickActive || iPanningActive ) |
|
631 { |
|
632 if ( ( aOffset>0 && iListTopIndex <= listBottomLimit && iListTopIndex >= -iViewHeight ) || |
|
633 ( aOffset<0 && iListBottomIndex >= 0 && iListBottomIndex <= listBottomLimit+iViewHeight ) ) |
|
634 { |
|
635 if ( iPhysics ) |
|
636 { |
|
637 TTouchFeedbackType feedbackType = ETouchFeedbackVibra; |
|
638 switch( iPhysics->OngoingPhysicsAction() ) |
|
639 { |
|
640 case CAknPhysics::EAknPhysicsActionDragging: |
|
641 { |
|
642 feedbackType = static_cast<TTouchFeedbackType> ( ETouchFeedbackVibra | ETouchFeedbackAudio ); |
|
643 } |
|
644 case CAknPhysics::EAknPhysicsActionFlicking: |
|
645 case CAknPhysics::EAknPhysicsActionBouncing: |
|
646 { |
|
647 ImmediateFeedback( ETouchFeedbackSensitiveList, |
|
648 feedbackType ); |
|
649 break; |
|
650 } |
|
651 default: |
|
652 break; |
|
653 } |
|
654 } |
|
655 } |
|
656 } |
|
657 } |
|
658 _AKNTRACE_FUNC_EXIT; |
|
659 } |
|
660 |
|
661 void CEikMenuPaneExtension::RestoreOffset( TInt aKeyCode ) |
|
662 { |
|
663 if ( aKeyCode == 0 ) |
|
664 { |
|
665 return; |
|
666 } |
|
667 _AKNTRACE_FUNC_ENTER; |
|
668 TPoint oldViewPos = iViewPosition; |
|
669 |
|
670 TInt itemsInRect = iControl->NumberOfItemsThatFitInView(); |
|
671 TInt topItem = iControl->iScroller->TopItemIndex(); |
|
672 TInt bottomItem = topItem + itemsInRect; |
|
673 TInt highLightItem = iControl->iSelectedItem; |
|
674 |
|
675 // There is partially visible items in menu. Offset is restored here if highlight |
|
676 // is moved to partially visible item by using hw keys (up/down) |
|
677 if ( ( highLightItem == topItem + 1 || highLightItem == topItem ) |
|
678 && aKeyCode == EKeyUpArrow ) |
|
679 { |
|
680 iViewPosition.iY += iVerticalOffset; |
|
681 } |
|
682 //ENothingSelected is for sct row. |
|
683 else if ( ( highLightItem == bottomItem - 1 |
|
684 || highLightItem == bottomItem |
|
685 || highLightItem == CEikMenuPane::ENothingSelected |
|
686 ) && aKeyCode == EKeyDownArrow ) |
|
687 { |
|
688 iViewPosition.iY += iControl->iItemHeight + iVerticalOffset; |
|
689 } |
|
690 // Submenu can be opened with left or right key depending on layout |
|
691 // or with selection keys |
|
692 else if ( ( !AknLayoutUtils::LayoutMirrored() && aKeyCode == EKeyRightArrow ) || |
|
693 ( AknLayoutUtils::LayoutMirrored() && aKeyCode == EKeyLeftArrow ) || |
|
694 aKeyCode == EKeyEnter || aKeyCode == EKeyOK || aKeyCode == EAknSoftkeyOk || |
|
695 aKeyCode == EAknSoftkeySelect || aKeyCode == EAknSoftkeyOk ) |
|
696 { |
|
697 if ( highLightItem != CEikMenuPane::ENothingSelected ) |
|
698 { |
|
699 const CEikMenuPaneItem* item = (*iControl->iItemArray)[highLightItem]; |
|
700 // Check if item has submenu |
|
701 if ( item->iData.iCascadeId ) |
|
702 { |
|
703 // Submenu is going to be opened from partial item, we need |
|
704 // to bring it fully visible |
|
705 if ( highLightItem == topItem ) |
|
706 { |
|
707 iViewPosition.iY += iVerticalOffset; |
|
708 } |
|
709 else if ( highLightItem == bottomItem ) |
|
710 { |
|
711 iViewPosition.iY += iControl->iItemHeight + iVerticalOffset; |
|
712 } |
|
713 } |
|
714 } |
|
715 } |
|
716 |
|
717 // Avoid redraw if position not changed |
|
718 if ( oldViewPos != iViewPosition ) |
|
719 { |
|
720 // Report view position change to scroll physics |
|
721 // when sub menu is opened with hw keys. |
|
722 _AKNTRACE( "[%s]", " ViewPositionChanged( iViewPosition )" ); |
|
723 ViewPositionChanged( iViewPosition ); |
|
724 } |
|
725 _AKNTRACE_FUNC_EXIT; |
|
726 } |
|
727 |
|
728 void CEikMenuPaneExtension::SetOffset( TInt aOffset ) |
|
729 { |
|
730 iVerticalOffset = aOffset; |
|
731 _AKNTRACE( "iVerticalOffset = %d", iVerticalOffset ); |
|
732 } |
|
733 |
|
734 |
|
735 void CEikMenuPaneExtension::PhysicEmulationEnded() |
|
736 { |
|
737 _AKNTRACE_FUNC_ENTER; |
|
738 iFlickActive = EFalse; |
|
739 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
740 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iGc ); |
|
741 |
|
742 if ( tfxApi ) |
|
743 { |
|
744 tfxApi->EnableEffects( ETrue ); |
|
745 } |
|
746 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
747 _AKNTRACE_FUNC_EXIT; |
|
748 } |
|
749 |
|
750 TPoint CEikMenuPaneExtension::ViewPosition() const |
|
751 { |
|
752 _AKNTRACE( "iViewPosition(%d,%d)", iViewPosition.iX, iViewPosition.iY ); |
|
753 return iViewPosition; |
|
754 } |
|
755 // |
|
756 // ============================================================================= |
|
757 // Helper class that monitor redirection changes declaration & definition |
|
758 // ============================================================================= |
|
759 /* |
|
760 * CRedirectionListener |
|
761 * |
|
762 * Delays opening of submenus during appear transitions |
|
763 */ |
|
764 NONSHARABLE_CLASS( CRedirectionListener ) : public CBase, |
|
765 public MAknTransitionUtilsObserver |
|
766 { |
|
767 public: |
|
768 CRedirectionListener( CEikMenuPaneExtension& aOwner ); |
|
769 ~CRedirectionListener(); |
|
770 |
|
771 void AppearTransitionStarting(); |
|
772 void Closing(); |
|
773 void LaunchCascadeMenu(); |
|
774 private: |
|
775 TInt AknTransitionCallback( TInt aEvent, TInt aState, |
|
776 const TDesC8* /*aParams*/ ); |
|
777 private: // Data |
|
778 TBool iObserving; |
|
779 TBool iTransitionUpcoming; |
|
780 TBool iAppearTransitionRunning; |
|
781 TBool iLaunchWhenUnredirected; |
|
782 CEikMenuPaneExtension& iOwner; |
|
783 }; |
|
784 |
|
785 // ----------------------------------------------------------------------------- |
|
786 // CRedirectionListener::CRedirectionListener |
|
787 // ----------------------------------------------------------------------------- |
|
788 // |
|
789 CRedirectionListener::CRedirectionListener( CEikMenuPaneExtension& aOwner ) : |
|
790 iOwner( aOwner ) |
|
791 { |
|
792 } |
|
793 |
|
794 // ----------------------------------------------------------------------------- |
|
795 // CRedirectionListener::~CRedirectionListener |
|
796 // ----------------------------------------------------------------------------- |
|
797 // |
|
798 CRedirectionListener::~CRedirectionListener() |
|
799 { |
|
800 Closing(); |
|
801 } |
|
802 |
|
803 // ----------------------------------------------------------------------------- |
|
804 // CRedirectionListener::AppearTransitionStarting |
|
805 // ----------------------------------------------------------------------------- |
|
806 // |
|
807 void CRedirectionListener::AppearTransitionStarting() |
|
808 { |
|
809 TInt err = KErrNone; |
|
810 iAppearTransitionRunning = EFalse; |
|
811 if ( !iObserving ) |
|
812 { |
|
813 err = CAknTransitionUtils::AddObserver( this, |
|
814 CAknTransitionUtils::EEventWsBufferRedirection ); |
|
815 } |
|
816 // Only set this value if observing |
|
817 if ( err == KErrNone ) |
|
818 { |
|
819 iObserving = ETrue; |
|
820 iTransitionUpcoming = ETrue; |
|
821 } |
|
822 } |
|
823 |
|
824 // ----------------------------------------------------------------------------- |
|
825 // CRedirectionListener::Closing |
|
826 // ----------------------------------------------------------------------------- |
|
827 // |
|
828 void CRedirectionListener::Closing() |
|
829 { |
|
830 if ( iObserving ) |
|
831 { |
|
832 CAknTransitionUtils::RemoveObserver( this, |
|
833 CAknTransitionUtils::EEventWsBufferRedirection ); |
|
834 iObserving = EFalse; |
|
835 } |
|
836 iTransitionUpcoming = EFalse; |
|
837 iLaunchWhenUnredirected = EFalse; |
|
838 } |
|
839 |
|
840 // ----------------------------------------------------------------------------- |
|
841 // CRedirectionListener::LaunchCascadeMenuL |
|
842 // ----------------------------------------------------------------------------- |
|
843 // |
|
844 void CRedirectionListener::LaunchCascadeMenu() |
|
845 { |
|
846 if ( iTransitionUpcoming && iObserving ) |
|
847 { |
|
848 // Get current redirection status |
|
849 TInt redirected; |
|
850 TInt err = RProperty::Get( KPSUidAvkonDomain, |
|
851 KAknTfxServerRedirectionStatus, |
|
852 redirected ); |
|
853 |
|
854 if ( err == KErrNone && redirected ) |
|
855 { |
|
856 // Transition has started |
|
857 iAppearTransitionRunning = ETrue; |
|
858 } |
|
859 } |
|
860 |
|
861 if ( iAppearTransitionRunning ) |
|
862 { |
|
863 // Lauch submenu when unredireted if currently in transition |
|
864 iLaunchWhenUnredirected = ETrue; |
|
865 } |
|
866 else |
|
867 { |
|
868 // Launch submenu imediately if not currently in transition |
|
869 iOwner.StartCascadeMenuAppearTransition(); |
|
870 iLaunchWhenUnredirected = EFalse; |
|
871 } |
|
872 } |
|
873 |
|
874 // ----------------------------------------------------------------------------- |
|
875 // CRedirectionListener::AknTransitionCallback |
|
876 // ----------------------------------------------------------------------------- |
|
877 // |
|
878 TInt CRedirectionListener::AknTransitionCallback( TInt aEvent, TInt aState, |
|
879 const TDesC8* /*aParams*/ ) |
|
880 { |
|
881 if ( aEvent == CAknTransitionUtils::EEventWsBufferRedirection ) |
|
882 { |
|
883 if ( aState) |
|
884 { |
|
885 // Redirected (transition started) |
|
886 // Don't display submenu until unredirected |
|
887 iAppearTransitionRunning = iTransitionUpcoming; |
|
888 } |
|
889 else |
|
890 { |
|
891 // Unredirected (transition finished) |
|
892 iAppearTransitionRunning = EFalse; |
|
893 if ( iLaunchWhenUnredirected ) |
|
894 { |
|
895 // Launch submenu waiting to be opened |
|
896 iOwner.StartCascadeMenuAppearTransition(); |
|
897 iLaunchWhenUnredirected = EFalse; |
|
898 } |
|
899 } |
|
900 iTransitionUpcoming = EFalse; |
|
901 } |
|
902 return 0; |
|
903 } |
|
904 |
|
905 // ----------------------------------------------------------------------------- |
|
906 // CEikMenuPaneExtension::StartCascadeMenuAppearTransition |
|
907 // ----------------------------------------------------------------------------- |
|
908 // |
|
909 void CEikMenuPaneExtension::StartCascadeMenuAppearTransition() |
|
910 { |
|
911 CEikMenuPane* cascadeMenuPane = iControl->iCascadeMenuPane; |
|
912 if ( cascadeMenuPane ) |
|
913 { |
|
914 cascadeMenuPane->SetParent( iControl ); |
|
915 GfxTransEffect::Begin( cascadeMenuPane, KGfxControlAppearAction ); |
|
916 cascadeMenuPane->StartDisplayingMenuPane( iControl->iHotKeyTable, |
|
917 iControl->Position(), |
|
918 NULL, |
|
919 0, |
|
920 EPopupTargetBottomLeft ); |
|
921 |
|
922 GfxTransEffect::SetDemarcation( cascadeMenuPane, iCascadeDRect ); |
|
923 GfxTransEffect::End( cascadeMenuPane ); |
|
924 |
|
925 // Transfer focus to cascade menu (highlight animations adapt to focus |
|
926 // change) |
|
927 cascadeMenuPane->SetFocus( ETrue, EDrawNow ); |
|
928 iControl->SetFocus( EFalse, EDrawNow ); |
|
929 } |
|
930 } |
|
931 |
|
932 // ----------------------------------------------------------------------------- |
|
933 // CEikMenuPaneExtension::CEikMenuPaneExtension |
|
934 // High CActive priority is well argumented because running the active object |
|
935 // will result in animation deletion -> results in freeing resources. |
|
936 // ----------------------------------------------------------------------------- |
|
937 // |
|
938 CEikMenuPaneExtension::CEikMenuPaneExtension() : |
|
939 CActive( EPriorityHigh ), |
|
940 // Initialise data members to zero |
|
941 iCascadeBitmap( NULL ), |
|
942 iCascadeBitmapMask( NULL ), |
|
943 iBgContext( NULL ), |
|
944 iSubMenuWidthIndex( 1 ), |
|
945 iCheckMarkBitmap( NULL ), |
|
946 iCheckMarkBitmapMask( NULL ), |
|
947 iRadioButtonBitmap( NULL ), |
|
948 iRadioButtonBitmapMask( NULL ), |
|
949 iHasRadioGroup( EFalse ), |
|
950 iSelectedRadioButtonItem( KNoSelectedRadioButtonItem ), |
|
951 iGrabbingCBAComponent( NULL ), |
|
952 iControl( NULL ), |
|
953 iAnimation( NULL ), |
|
954 iAnimFlags ( 0 ), |
|
955 iSct( NULL ), |
|
956 iSctHighlighted( EFalse ), |
|
957 iSpecialCharPointed( EFalse ) |
|
958 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
959 ,iGc ( NULL ) |
|
960 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
961 ,iVerticalOffset( 0 ) |
|
962 ,iPhysics( NULL ) |
|
963 ,iListTopIndex( 0 ) |
|
964 ,iViewHeight( 0 ) |
|
965 ,iFlickActive( EFalse ) |
|
966 ,iPanningActive( EFalse ) |
|
967 ,iFeedback( MTouchFeedback::Instance() ) |
|
968 ,iLastFeedbackTopItemIndex( 0 ) |
|
969 { |
|
970 iIsPenEnable = AknLayoutUtils::PenEnabled(); |
|
971 iItemsReadyForPenSelection = !iIsPenEnable; |
|
972 iNextHighlightItem = KErrNotFound; |
|
973 } |
|
974 |
|
975 // ----------------------------------------------------------------------------- |
|
976 // CEikMenuPaneExtension::~CEikMenuPaneExtension |
|
977 // Destructor for extension class |
|
978 // ----------------------------------------------------------------------------- |
|
979 // |
|
980 CEikMenuPaneExtension::~CEikMenuPaneExtension() |
|
981 { |
|
982 _AKNTRACE_FUNC_ENTER; |
|
983 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
984 if ( CAknListLoader::TfxApiInternal( iGc ) ) |
|
985 { |
|
986 delete iGc; |
|
987 } |
|
988 #endif |
|
989 Cancel(); // Cancel possibly pending request |
|
990 |
|
991 // Stop receiving foreground events |
|
992 CCoeEnv* env = CCoeEnv::Static(); |
|
993 env->RemoveForegroundObserver( *this ); |
|
994 |
|
995 delete iCascadeBitmap; |
|
996 iCascadeBitmap = NULL; |
|
997 |
|
998 delete iCascadeBitmapMask; |
|
999 iCascadeBitmapMask = NULL; |
|
1000 |
|
1001 delete iBgContext; |
|
1002 iBgContext = NULL; |
|
1003 |
|
1004 delete iCheckMarkBitmap; |
|
1005 iCheckMarkBitmap = NULL; |
|
1006 |
|
1007 delete iCheckMarkBitmapMask; |
|
1008 iCheckMarkBitmapMask = NULL; |
|
1009 |
|
1010 delete iRadioButtonBitmap; |
|
1011 iRadioButtonBitmap = NULL; |
|
1012 |
|
1013 delete iRadioButtonBitmapMask; |
|
1014 iRadioButtonBitmapMask = NULL; |
|
1015 |
|
1016 iControl = NULL; |
|
1017 |
|
1018 delete iAnimation; |
|
1019 iAnimation = NULL; |
|
1020 |
|
1021 delete iSct; |
|
1022 iSct = NULL; |
|
1023 |
|
1024 delete iCascadeMenuObject; |
|
1025 iCascadeMenuObject = NULL; |
|
1026 |
|
1027 delete iTimer; |
|
1028 iTimer = NULL; |
|
1029 |
|
1030 delete iHighlightTimer; |
|
1031 iHighlightTimer = NULL; |
|
1032 |
|
1033 if ( iTaskSwapIdle ) |
|
1034 { |
|
1035 if ( iTaskSwapIdle->IsActive() ) |
|
1036 { |
|
1037 iTaskSwapIdle->Cancel(); |
|
1038 TaskSwapCallBack( NULL ); |
|
1039 } |
|
1040 delete iTaskSwapIdle; |
|
1041 } |
|
1042 |
|
1043 delete iRedirectionListener; |
|
1044 delete iPhysics; |
|
1045 _AKNTRACE_FUNC_EXIT; |
|
1046 } |
|
1047 |
|
1048 // ----------------------------------------------------------------------------- |
|
1049 // CEikMenuPaneExtension::ConstructL |
|
1050 // ----------------------------------------------------------------------------- |
|
1051 // |
|
1052 void CEikMenuPaneExtension::ConstructL( CEikMenuPane* aControl ) |
|
1053 { |
|
1054 ASSERT( aControl ); |
|
1055 iControl = aControl; |
|
1056 iAnimFlags.Set( EFlagUseAnimation ); // Animations are created by default |
|
1057 CActiveScheduler::Add( this ); |
|
1058 iDraggedOutside = EFalse; |
|
1059 iLaunchCascadeMenu = EFalse; |
|
1060 iButtonDownItem = KErrNotFound; |
|
1061 iTaskSwapIdle = CIdle::NewL( CActive::EPriorityHigh ); |
|
1062 if ( aControl->iOwner == NULL && GfxTransEffect::IsRegistered( aControl ) ) |
|
1063 { |
|
1064 // Delays submenu opening during appear transitions |
|
1065 iRedirectionListener = new ( ELeave ) CRedirectionListener( *this ); |
|
1066 } |
|
1067 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1068 iGc = CAknListLoader::CreateTfxGc( *aControl, |
|
1069 iControl->iScroller->iTopItemIndex, |
|
1070 iTotalNumberOfItemsInView ); |
|
1071 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
1072 if ( static_cast<CAknAppUi*>( |
|
1073 iControl->ControlEnv()->AppUi() )->IsSingleClickCompatible() ) |
|
1074 { |
|
1075 iFlags.Set( ESingleClickEnabled ); |
|
1076 } |
|
1077 |
|
1078 if ( !iPhysics ) |
|
1079 { |
|
1080 iPhysics = CAknPhysics::NewL( *this, iControl ); |
|
1081 } |
|
1082 |
|
1083 iBgContext = CAknsFrameBackgroundControlContext::NewL( |
|
1084 KAknsIIDQsnFrPopup, TRect( 0, 0, 1, 1 ), TRect( 0, 0, 1, 1 ), EFalse ); |
|
1085 } |
|
1086 |
|
1087 // ----------------------------------------------------------------------------- |
|
1088 // CEikMenuPaneExtension::CreateAnimation |
|
1089 // ----------------------------------------------------------------------------- |
|
1090 // |
|
1091 void CEikMenuPaneExtension::CreateAnimation() |
|
1092 { |
|
1093 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1094 return; |
|
1095 #else |
|
1096 if( !iAnimation && iAnimFlags.IsSet( EFlagUseAnimation ) ) |
|
1097 { |
|
1098 TRect rect = iControl->HighlightRect(); |
|
1099 TRAPD( err, CreateAnimationL( rect.Size() ) ); |
|
1100 if( KErrNone != err ) |
|
1101 { |
|
1102 // Animation has not been drawn -> no need for repaint |
|
1103 UseNoAnimation(); |
|
1104 } |
|
1105 } |
|
1106 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
1107 } |
|
1108 |
|
1109 // ----------------------------------------------------------------------------- |
|
1110 // CEikMenuPaneExtension::NoAnimIfError |
|
1111 // ----------------------------------------------------------------------------- |
|
1112 // |
|
1113 void CEikMenuPaneExtension::NoAnimIfError( TInt aError ) |
|
1114 { |
|
1115 if( KErrNone != aError ) |
|
1116 UseNoAnimation(); |
|
1117 } |
|
1118 |
|
1119 // ----------------------------------------------------------------------------- |
|
1120 // CEikMenuPaneExtension::UseNoAnimation |
|
1121 // Falls back to normal highlight rendering. |
|
1122 // ----------------------------------------------------------------------------- |
|
1123 // |
|
1124 void CEikMenuPaneExtension::UseNoAnimation() |
|
1125 { |
|
1126 delete iAnimation; |
|
1127 iAnimation = NULL; |
|
1128 |
|
1129 // Do not attempt to create animations in the future |
|
1130 iAnimFlags.Clear( EFlagUseAnimation ); |
|
1131 |
|
1132 // Stop receiving foreground events |
|
1133 CCoeEnv* env = CCoeEnv::Static(); |
|
1134 env->RemoveForegroundObserver( *this ); |
|
1135 } |
|
1136 |
|
1137 // ----------------------------------------------------------------------------- |
|
1138 // CEikMenuPaneExtension::StartCascadeMenuTimerL |
|
1139 // Starts the timer for the sub menu launch. Timer is constructed when used for |
|
1140 // the first time |
|
1141 // ----------------------------------------------------------------------------- |
|
1142 // |
|
1143 void CEikMenuPaneExtension::StartCascadeMenuTimerL() |
|
1144 { |
|
1145 _AKNTRACE_FUNC_ENTER; |
|
1146 if ( !iTimer ) |
|
1147 { |
|
1148 iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
1149 } |
|
1150 else if ( iTimer->IsActive() ) |
|
1151 { |
|
1152 iTimer->Cancel(); |
|
1153 } |
|
1154 iTimer->Start( KCascadeMenuOpenDelay, |
|
1155 KCascadeMenuOpenDelay, |
|
1156 TCallBack ( CascadeMenuTimerCallBack, this ) ); |
|
1157 _AKNTRACE_FUNC_EXIT; |
|
1158 } |
|
1159 |
|
1160 // ----------------------------------------------------------------------------- |
|
1161 // CEikMenuPaneExtension::StopCascadeMenuTimer |
|
1162 // Stops the timer for the sub menu launch |
|
1163 // ----------------------------------------------------------------------------- |
|
1164 // |
|
1165 void CEikMenuPaneExtension::StopCascadeMenuTimer() |
|
1166 { |
|
1167 _AKNTRACE_FUNC_ENTER; |
|
1168 if ( iTimer && iTimer->IsActive() ) |
|
1169 { |
|
1170 iTimer->Cancel(); |
|
1171 } |
|
1172 iLaunchCascadeMenu = EFalse; |
|
1173 _AKNTRACE_FUNC_EXIT; |
|
1174 } |
|
1175 |
|
1176 // ----------------------------------------------------------------------------- |
|
1177 // CEikMenuPaneExtension::CascadeMenuTimerCallBack |
|
1178 // Callback function of the timer for the sub menu launch |
|
1179 // ----------------------------------------------------------------------------- |
|
1180 // |
|
1181 TInt CEikMenuPaneExtension::CascadeMenuTimerCallBack( TAny* aThis ) |
|
1182 { |
|
1183 _AKNTRACE_FUNC_ENTER; |
|
1184 CEikMenuPaneExtension* self = |
|
1185 reinterpret_cast <CEikMenuPaneExtension*> ( aThis ); |
|
1186 self->iLaunchCascadeMenu = ETrue; |
|
1187 _AKNTRACE_FUNC_EXIT; |
|
1188 return KErrNone; |
|
1189 } |
|
1190 |
|
1191 // ----------------------------------------------------------------------------- |
|
1192 // CEikMenuPaneExtension::IsCascadeMenuTimerActive |
|
1193 // Returns ETrue if timer is active |
|
1194 // ----------------------------------------------------------------------------- |
|
1195 // |
|
1196 TBool CEikMenuPaneExtension::IsCascadeMenuTimerActive() |
|
1197 { |
|
1198 if ( !iTimer ) |
|
1199 { |
|
1200 return EFalse; |
|
1201 } |
|
1202 return iTimer->IsActive(); |
|
1203 } |
|
1204 |
|
1205 |
|
1206 // ----------------------------------------------------------------------------- |
|
1207 // CEikMenuPaneExtension::StartHighlightTimerL |
|
1208 // Starts the timer for the pressed down highlight activation. |
|
1209 // Timer is constructed when used for the first time |
|
1210 // ----------------------------------------------------------------------------- |
|
1211 // |
|
1212 void CEikMenuPaneExtension::StartHighlightTimerL() |
|
1213 { |
|
1214 _AKNTRACE_FUNC_ENTER; |
|
1215 if ( !iHighlightTimer ) |
|
1216 { |
|
1217 iHighlightTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
1218 if ( !iHighlightTimer ) |
|
1219 { |
|
1220 return; |
|
1221 } |
|
1222 } |
|
1223 else if ( iHighlightTimer->IsActive() ) |
|
1224 { |
|
1225 iHighlightTimer->Cancel(); |
|
1226 } |
|
1227 |
|
1228 TInt timeout ( 0 ); |
|
1229 if ( iPhysics ) |
|
1230 { |
|
1231 timeout = iPhysics->HighlightTimeout() * 1000; |
|
1232 } |
|
1233 iPressedDown = EFalse; |
|
1234 iHighlightTimer->Start( timeout,timeout, |
|
1235 TCallBack ( HighlightTimerCallBack, this ) ); |
|
1236 _AKNTRACE_FUNC_EXIT; |
|
1237 } |
|
1238 |
|
1239 |
|
1240 // --------------------------------------------------------------------------- |
|
1241 // CEikMenuPaneExtension::ResetPressedHighlight |
|
1242 // Stops the timer for the pressed down highlight activation and resets the |
|
1243 // pressed highlight |
|
1244 // --------------------------------------------------------------------------- |
|
1245 // |
|
1246 void CEikMenuPaneExtension::ResetPressedHighlight() |
|
1247 { |
|
1248 _AKNTRACE_FUNC_ENTER; |
|
1249 if ( HighlightTimerActive() ) |
|
1250 { |
|
1251 iHighlightTimer->Cancel(); |
|
1252 } |
|
1253 |
|
1254 // if status changed repaint needed |
|
1255 if ( iPressedDown ) |
|
1256 { |
|
1257 iPressedDown = EFalse; |
|
1258 iControl->RepaintHighlight(); |
|
1259 } |
|
1260 _AKNTRACE_FUNC_EXIT; |
|
1261 } |
|
1262 |
|
1263 // ----------------------------------------------------------------------------- |
|
1264 // CEikMenuPaneExtension::HighlightTimerCallBack |
|
1265 // Callback function of the timer for pressed down highlight |
|
1266 // ----------------------------------------------------------------------------- |
|
1267 // |
|
1268 TInt CEikMenuPaneExtension::HighlightTimerCallBack( TAny* aThis ) |
|
1269 { |
|
1270 _AKNTRACE_FUNC_ENTER; |
|
1271 CEikMenuPaneExtension* self = |
|
1272 reinterpret_cast <CEikMenuPaneExtension*> ( aThis ); |
|
1273 self->iPressedDown = ETrue; |
|
1274 if ( self->iControl->SelectedItem() == self->iNextHighlightItem ) |
|
1275 { |
|
1276 self->iControl->RepaintHighlight(); |
|
1277 } |
|
1278 else |
|
1279 { |
|
1280 if ( self->iNextHighlightItem != KErrNotFound ) |
|
1281 { |
|
1282 self->iControl->MoveHighlightTo( self->iNextHighlightItem ); |
|
1283 } |
|
1284 } |
|
1285 self->iNextHighlightItem = KErrNotFound; |
|
1286 if ( self->HighlightTimerActive() ) |
|
1287 { |
|
1288 self->iHighlightTimer->Cancel(); |
|
1289 } |
|
1290 _AKNTRACE_FUNC_EXIT; |
|
1291 return KErrNone; |
|
1292 } |
|
1293 |
|
1294 |
|
1295 // --------------------------------------------------------------------------- |
|
1296 // Checks if the highlight timer is running. |
|
1297 // --------------------------------------------------------------------------- |
|
1298 // |
|
1299 TBool CEikMenuPaneExtension::HighlightTimerActive() const |
|
1300 { |
|
1301 return ( iHighlightTimer && iHighlightTimer->IsActive() ); |
|
1302 } |
|
1303 |
|
1304 |
|
1305 // ----------------------------------------------------------------------------- |
|
1306 // CEikMenuPaneExtension::ChangePosition |
|
1307 // Position of aPointerEvent should be modified when point in beside scrollbar. |
|
1308 // ----------------------------------------------------------------------------- |
|
1309 // |
|
1310 void CEikMenuPaneExtension::ChangePosition( TPointerEvent& aPointerEvent ) |
|
1311 { |
|
1312 if ( !iControl->iSBFrame ) |
|
1313 { |
|
1314 iControl->CreateScrollBarFrame(); |
|
1315 } |
|
1316 TRect scrollBarRect = iControl->iSBFrame->VerticalScrollBar()->Rect(); |
|
1317 TPoint scrollerTl = scrollBarRect.iTl; |
|
1318 TPoint scrollerBr = scrollBarRect.iBr; |
|
1319 TRect gapRect; |
|
1320 // For layout that left to right |
|
1321 if ( !AknLayoutUtils::LayoutMirrored() ) |
|
1322 { |
|
1323 TPoint rectTl( scrollerBr.iX, iControl->Rect().iTl.iY ); |
|
1324 gapRect.SetRect( rectTl, iControl->Rect().iBr ); |
|
1325 } |
|
1326 // For layout that right to left |
|
1327 else |
|
1328 { |
|
1329 TPoint rectBr( scrollerTl.iX, iControl->Rect().iBr.iY ); |
|
1330 gapRect.SetRect( iControl->Rect().iTl, rectBr ); |
|
1331 } |
|
1332 |
|
1333 if ( gapRect.Contains( aPointerEvent.iPosition ) ) |
|
1334 { |
|
1335 if ( !AknLayoutUtils::LayoutMirrored() ) |
|
1336 { |
|
1337 aPointerEvent.iPosition.iX = scrollerBr.iX - 1; |
|
1338 } |
|
1339 else |
|
1340 { |
|
1341 aPointerEvent.iPosition.iX = scrollerTl.iX; |
|
1342 } |
|
1343 //Modify y coordinate of point in top left/right corner of options menu |
|
1344 if ( aPointerEvent.iPosition.iY < scrollerTl.iY ) |
|
1345 { |
|
1346 aPointerEvent.iPosition.iY = scrollerTl.iY; |
|
1347 } |
|
1348 //Modify y coordinate of point in bottom left/right corner of options menu |
|
1349 if ( aPointerEvent.iPosition.iY > scrollerBr.iY ) |
|
1350 { |
|
1351 aPointerEvent.iPosition.iY = scrollerBr.iY - 1; |
|
1352 } |
|
1353 } |
|
1354 } |
|
1355 |
|
1356 |
|
1357 // ----------------------------------------------------------------------------- |
|
1358 // CEikMenuPaneExtension::CalculateParentEvent |
|
1359 // Calculate parent event for sub menu. |
|
1360 // ----------------------------------------------------------------------------- |
|
1361 // |
|
1362 void CEikMenuPaneExtension::CalculateParentEvent( const TPointerEvent& aPointerEvent, |
|
1363 TPointerEvent& aParentEvent ) |
|
1364 { |
|
1365 aParentEvent.iModifiers = aPointerEvent.iModifiers; |
|
1366 TPoint subPos = iControl->PositionRelativeToScreen(); |
|
1367 TPoint ownerPos = iControl->iOwner->PositionRelativeToScreen(); |
|
1368 aParentEvent.iPosition.SetXY ( |
|
1369 aPointerEvent.iPosition.iX + subPos.iX - ownerPos.iX, |
|
1370 aPointerEvent.iPosition.iY + subPos.iY - ownerPos.iY); |
|
1371 aParentEvent.iType = aPointerEvent.iType; |
|
1372 } |
|
1373 |
|
1374 // ----------------------------------------------------------------------------- |
|
1375 // CEikMenuPaneExtension::GetBackgroundRect |
|
1376 // Get background rect for landscape mode of menu pane. |
|
1377 // ----------------------------------------------------------------------------- |
|
1378 // |
|
1379 TRect CEikMenuPaneExtension::GetBackgroundRect( const TRect& aWindowRect ) const |
|
1380 { |
|
1381 return aWindowRect; |
|
1382 } |
|
1383 |
|
1384 // ----------------------------------------------------------------------------- |
|
1385 // CEikMenuPaneExtension::AdjustPopupLayoutData |
|
1386 // Adjust popup layout data for main menu pane in landscape mode |
|
1387 // ----------------------------------------------------------------------------- |
|
1388 // |
|
1389 void CEikMenuPaneExtension::AdjustPopupLayoutData( TAknWindowLineLayout& aListScrollPaneLayout ) |
|
1390 { |
|
1391 TRect screenRect; |
|
1392 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect ); |
|
1393 AknLayoutUtils::TAknCbaLocation cbaPosition = AknLayoutUtils::CbaLocation(); |
|
1394 |
|
1395 if ( screenRect.Width() == EQhdWidth && screenRect.Height() == EQhdHeight |
|
1396 && cbaPosition == AknLayoutUtils::EAknCbaLocationBottom ) |
|
1397 { |
|
1398 if ( !AknLayoutUtils::LayoutMirrored() ) |
|
1399 { |
|
1400 aListScrollPaneLayout.ir -= 32; |
|
1401 } |
|
1402 else |
|
1403 { |
|
1404 aListScrollPaneLayout.il -= 32; |
|
1405 } |
|
1406 } |
|
1407 } |
|
1408 |
|
1409 |
|
1410 // ----------------------------------------------------------------------------- |
|
1411 // CEikMenuPaneExtension::GetMenuItemTextLayout |
|
1412 // Get Layout of menu item text. |
|
1413 // ----------------------------------------------------------------------------- |
|
1414 // |
|
1415 const TAknLayoutText CEikMenuPaneExtension::GetMenuItemTextLayout(const TRect& aItemRect, TBool cascade) |
|
1416 { |
|
1417 TAknTextLineLayout menuTextLayout; |
|
1418 |
|
1419 if ( !iControl->iOwner ) |
|
1420 { |
|
1421 menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine(); |
|
1422 } |
|
1423 else |
|
1424 { |
|
1425 if ( iHasIcon ) |
|
1426 { |
|
1427 menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() ); |
|
1428 } |
|
1429 else |
|
1430 { |
|
1431 menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() ); |
|
1432 } |
|
1433 } |
|
1434 |
|
1435 TAknLayoutText textRect; |
|
1436 textRect.LayoutText( aItemRect, menuTextLayout ); |
|
1437 return textRect; |
|
1438 } |
|
1439 |
|
1440 |
|
1441 // ----------------------------------------------------------------------------- |
|
1442 // CEikMenuPaneExtension::FocusGained |
|
1443 // The owning control has gained focus -> animation should be continued. |
|
1444 // ----------------------------------------------------------------------------- |
|
1445 // |
|
1446 void CEikMenuPaneExtension::FocusGained() |
|
1447 { |
|
1448 Play(); |
|
1449 } |
|
1450 |
|
1451 // ----------------------------------------------------------------------------- |
|
1452 // CEikMenuPaneExtension::FocusLost |
|
1453 // The owning control has lost focus -> no running animation (even if the |
|
1454 // control is partially visible). |
|
1455 // ----------------------------------------------------------------------------- |
|
1456 // |
|
1457 void CEikMenuPaneExtension::FocusLost() |
|
1458 { |
|
1459 if( iAnimation ) |
|
1460 { |
|
1461 NoAnimIfError( iAnimation->Pause() ); |
|
1462 } |
|
1463 } |
|
1464 |
|
1465 // ----------------------------------------------------------------------------- |
|
1466 // CEikMenuPaneExtension::HandleLayoutSwitch |
|
1467 // ----------------------------------------------------------------------------- |
|
1468 // |
|
1469 void CEikMenuPaneExtension::HandleLayoutSwitch() |
|
1470 { |
|
1471 if( iAnimation ) // Animation exists -> try to resize |
|
1472 { |
|
1473 TRect rect( iControl->HighlightRect() ); |
|
1474 |
|
1475 // Resize animation |
|
1476 TBool aboutToStart = ETrue; |
|
1477 if( iAnimation->State() == EAknsAnimStateStopped ) |
|
1478 aboutToStart = EFalse; |
|
1479 |
|
1480 TRAPD( err, DoResizeL( rect.Size(), aboutToStart ) ); |
|
1481 NoAnimIfError( err ); |
|
1482 } |
|
1483 } |
|
1484 |
|
1485 // ----------------------------------------------------------------------------- |
|
1486 // CEikMenuPaneExtension::ChangeHighlightBackground |
|
1487 // ----------------------------------------------------------------------------- |
|
1488 // |
|
1489 void CEikMenuPaneExtension::ChangeHighlightBackground() |
|
1490 { |
|
1491 // Every time the current list item is changed we need to change the |
|
1492 // animation input layer (animated element is the highlight bacground that |
|
1493 // can differ between highlight positions). |
|
1494 if( iAnimation ) |
|
1495 { |
|
1496 if( iAnimation->State() == EAknsAnimStateStopped ) |
|
1497 { |
|
1498 // Input layers don't exist when stopped or finished. We need to |
|
1499 // resize to create the input layers and to update the output |
|
1500 // layer. |
|
1501 |
|
1502 TRAPD( err, DoResizeL( iAnimation->Size(), EFalse ) ); |
|
1503 NoAnimIfError( err ); |
|
1504 } |
|
1505 else // Either paused, running or finished |
|
1506 { |
|
1507 // Update the highlight background |
|
1508 if( iAnimation->InputRgbGc() ) |
|
1509 DrawHighlightBackground( *iAnimation->InputRgbGc() ); |
|
1510 |
|
1511 // We need to update the output frame (otherwise the highlight |
|
1512 // would drawn with the old output before the next new animation |
|
1513 // frame). |
|
1514 NoAnimIfError( iAnimation->UpdateOutput() ); |
|
1515 } |
|
1516 } |
|
1517 } |
|
1518 |
|
1519 // ----------------------------------------------------------------------------- |
|
1520 // CEikMenuPaneExtension::MenuClosed |
|
1521 // ----------------------------------------------------------------------------- |
|
1522 // |
|
1523 void CEikMenuPaneExtension::MenuClosed() |
|
1524 { |
|
1525 _AKNTRACE_FUNC_ENTER; |
|
1526 delete iAnimation; |
|
1527 iAnimation = NULL; |
|
1528 |
|
1529 CCoeEnv* env = CCoeEnv::Static(); |
|
1530 env->RemoveForegroundObserver( *this ); |
|
1531 |
|
1532 iAnimFlags.Set( EFlagUseAnimation ); |
|
1533 |
|
1534 delete iSct; |
|
1535 iSct = NULL; |
|
1536 iSctHighlighted = EFalse; |
|
1537 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1538 iSctRect = TRect::EUninitialized; |
|
1539 #endif |
|
1540 |
|
1541 if ( iCba ) |
|
1542 { |
|
1543 iCba = NULL; |
|
1544 } |
|
1545 |
|
1546 if ( iRedirectionListener ) |
|
1547 { |
|
1548 iRedirectionListener->Closing(); |
|
1549 } |
|
1550 |
|
1551 iFlags.Clear( EHideItemSpecificCommands ); |
|
1552 iFlags.Clear( EContextSensitive ); |
|
1553 iFlags.Clear( EHighlightEnabled ); |
|
1554 _AKNTRACE_FUNC_EXIT; |
|
1555 } |
|
1556 |
|
1557 // ----------------------------------------------------------------------------- |
|
1558 // CEikMenuPaneExtension::HandleGainingForeground |
|
1559 // The application has gained foreground -> animation should be continued. |
|
1560 // ----------------------------------------------------------------------------- |
|
1561 // |
|
1562 void CEikMenuPaneExtension::HandleGainingForeground() |
|
1563 { |
|
1564 // It is safe to start animation in this method because animation is |
|
1565 // deleted when the menu is closed -> it is not possible that menu receives |
|
1566 // foreground event while it is not visible and the animation exists. |
|
1567 |
|
1568 // We need to check if the menu has focus (to prevent running nonfocused |
|
1569 // animation because also the nonfocused menu (menu/submenu) receives |
|
1570 // foreground events) |
|
1571 Play(); |
|
1572 } |
|
1573 |
|
1574 // ----------------------------------------------------------------------------- |
|
1575 // CEikMenuPaneExtension::HandleLosingForeground |
|
1576 // The application lost foreground -> no running animation (even if the |
|
1577 // application is partially visible). |
|
1578 // ----------------------------------------------------------------------------- |
|
1579 // |
|
1580 void CEikMenuPaneExtension::HandleLosingForeground() |
|
1581 { |
|
1582 if( iAnimation ) |
|
1583 { |
|
1584 NoAnimIfError( iAnimation->Stop() ); |
|
1585 } |
|
1586 } |
|
1587 |
|
1588 // ----------------------------------------------------------------------------- |
|
1589 // CEikMenuPaneExtension::AnimFrameReady |
|
1590 // ----------------------------------------------------------------------------- |
|
1591 // |
|
1592 void CEikMenuPaneExtension::AnimFrameReady( TInt aError, TInt ) |
|
1593 { |
|
1594 if( KErrNone != aError ) |
|
1595 { |
|
1596 // Animation has failed to run -> schedule the animation for |
|
1597 // deletion to fall back to normal rendering. |
|
1598 PostDeleteAnimation(); |
|
1599 } |
|
1600 else if( iControl ) // Frame ok |
|
1601 { |
|
1602 if ( iControl->IsVisible() ) |
|
1603 { |
|
1604 iControl->RepaintHighlight(); |
|
1605 } |
|
1606 } |
|
1607 } |
|
1608 |
|
1609 // ----------------------------------------------------------------------------- |
|
1610 // CEikMenuPaneExtension::DoCancel |
|
1611 // ----------------------------------------------------------------------------- |
|
1612 // |
|
1613 void CEikMenuPaneExtension::DoCancel() |
|
1614 { |
|
1615 // Required method, but not needed |
|
1616 } |
|
1617 |
|
1618 |
|
1619 // ----------------------------------------------------------------------------- |
|
1620 // CEikMenuPaneExtension::RunL |
|
1621 // Postponed animation deletion is done here |
|
1622 // ----------------------------------------------------------------------------- |
|
1623 // |
|
1624 void CEikMenuPaneExtension::RunL() |
|
1625 { |
|
1626 UseNoAnimation(); |
|
1627 } |
|
1628 |
|
1629 // ----------------------------------------------------------------------------- |
|
1630 // CEikMenuPaneExtension::Play |
|
1631 // ----------------------------------------------------------------------------- |
|
1632 // |
|
1633 void CEikMenuPaneExtension::Play() |
|
1634 { |
|
1635 if( !iAnimation || !iControl->IsFocused() ) |
|
1636 { |
|
1637 return; |
|
1638 } |
|
1639 |
|
1640 // No need to start running/finished animation |
|
1641 if( EAknsAnimStateRunning == iAnimation->State() || |
|
1642 EAknsAnimStateFinished == iAnimation->State() ) |
|
1643 { |
|
1644 return; |
|
1645 } |
|
1646 |
|
1647 CAknAppUi* aui = static_cast<CAknAppUi*>(CEikonEnv::Static()->AppUi()); |
|
1648 if( !aui->IsForeground() ) |
|
1649 { |
|
1650 return; |
|
1651 } |
|
1652 |
|
1653 if( EAknsAnimStatePaused == iAnimation->State() ) |
|
1654 { |
|
1655 NoAnimIfError( iAnimation->Continue() ); |
|
1656 } |
|
1657 else if( EAknsAnimStateStopped == iAnimation->State() ) |
|
1658 { |
|
1659 if( iAnimation->NeedsInputLayer() ) |
|
1660 { |
|
1661 TRAPD( err, DoResizeL( iAnimation->Size(), ETrue ) ); |
|
1662 NoAnimIfError( err ); |
|
1663 |
|
1664 if( KErrNone != err ) |
|
1665 return; |
|
1666 } |
|
1667 |
|
1668 NoAnimIfError( iAnimation->Start() ); |
|
1669 } |
|
1670 } |
|
1671 |
|
1672 // ----------------------------------------------------------------------------- |
|
1673 // CEikMenuPaneExtension::DrawHighlightBackground |
|
1674 // Draws skinned highlight background to the provided graphics context. |
|
1675 // ----------------------------------------------------------------------------- |
|
1676 // |
|
1677 TBool CEikMenuPaneExtension::DrawHighlightBackground( CFbsBitGc& aGc ) |
|
1678 { |
|
1679 // Draw the background under the current highlight. This simplified |
|
1680 // drawing, we only grab a piece from the list background bitmap. |
|
1681 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
1682 |
|
1683 return AknsDrawUtils::DrawBackground( skin, iBgContext, iControl, aGc, TPoint(0,0), |
|
1684 iControl->HighlightRect(), |
|
1685 KAknsDrawParamRGBOnly ); |
|
1686 } |
|
1687 |
|
1688 // ----------------------------------------------------------------------------- |
|
1689 // CEikMenuPaneExtension::PostDeleteAnimation |
|
1690 // Schedules the animation for deletion by activating the extension itself. |
|
1691 // Deletion is postponed because in many error/failure occasions the caller has |
|
1692 // been animation and direct deletion is possibly not safe (because function |
|
1693 // stack would return through the deleted object). |
|
1694 // ----------------------------------------------------------------------------- |
|
1695 // |
|
1696 void CEikMenuPaneExtension::PostDeleteAnimation() |
|
1697 { |
|
1698 TRequestStatus* status = &iStatus; |
|
1699 User::RequestComplete( status, KErrNone ); |
|
1700 SetActive(); |
|
1701 } |
|
1702 |
|
1703 // ----------------------------------------------------------------------------- |
|
1704 // CEikMenuPaneExtension::CreateAnimationL |
|
1705 // ----------------------------------------------------------------------------- |
|
1706 // |
|
1707 void CEikMenuPaneExtension::CreateAnimationL( const TSize& aHighlightSize ) |
|
1708 { |
|
1709 // Create animation |
|
1710 CCoeEnv* env = CCoeEnv::Static(); |
|
1711 env->AddForegroundObserverL( *this ); |
|
1712 |
|
1713 delete iAnimation; |
|
1714 iAnimation = NULL; |
|
1715 |
|
1716 iAnimation = CAknsEffectAnim::NewL( this ); |
|
1717 TBool ok = iAnimation->ConstructFromSkinL( KAknsIIDQsnAnimList ); |
|
1718 |
|
1719 if( !ok ) // Animation for the ID was not found from the skin |
|
1720 { |
|
1721 User::Leave( KErrNotFound ); |
|
1722 } |
|
1723 |
|
1724 DoResizeL( aHighlightSize, ETrue ); |
|
1725 |
|
1726 Play(); |
|
1727 } |
|
1728 |
|
1729 // ----------------------------------------------------------------------------- |
|
1730 // CEikMenuPaneExtension::DoResizeL |
|
1731 // ----------------------------------------------------------------------------- |
|
1732 // |
|
1733 void CEikMenuPaneExtension::DoResizeL( |
|
1734 const TSize& aHighlightSize, TBool aAboutToStart ) |
|
1735 { |
|
1736 iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart ); |
|
1737 |
|
1738 if( iAnimation->InputRgbGc() ) |
|
1739 DrawHighlightBackground( *iAnimation->InputRgbGc() ); |
|
1740 |
|
1741 iAnimation->EndConfigInputLayersL(); |
|
1742 } |
|
1743 |
|
1744 // ----------------------------------------------------------------------------- |
|
1745 // CEikMenuPaneExtension::ConstructMenuSctRowL |
|
1746 // Creates a special characters row to be used in edit menu. |
|
1747 // ----------------------------------------------------------------------------- |
|
1748 // |
|
1749 void CEikMenuPaneExtension::ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId ) |
|
1750 { |
|
1751 _AKNTRACE_FUNC_ENTER; |
|
1752 TBool renew = EFalse; |
|
1753 if (iSct) |
|
1754 { |
|
1755 delete iSct; |
|
1756 iSct = NULL; |
|
1757 renew = ETrue; |
|
1758 } |
|
1759 iSct = new(ELeave) CAknCharMap(); |
|
1760 iSct->ConstructMenuSctRowL(aResourceId); |
|
1761 iSct->SetBuffer( aSpecialChars ); |
|
1762 if ( renew && iMenuPaneWindow && iControl ) |
|
1763 { |
|
1764 iSct->SetContainerWindowL( *iControl ); |
|
1765 if ( AknLayoutUtils::PenEnabled() ) |
|
1766 { |
|
1767 iSct->SetGloballyCapturing( ETrue ); |
|
1768 iSct->SetPointerCapture( ETrue ); |
|
1769 } |
|
1770 } |
|
1771 _AKNTRACE_FUNC_EXIT; |
|
1772 } |
|
1773 |
|
1774 // ----------------------------------------------------------------------------- |
|
1775 // CEikMenuPaneExtension::ConstructMenuSctRowFromDialogL |
|
1776 // Creates a special characters row to be used in edit menu. |
|
1777 // ----------------------------------------------------------------------------- |
|
1778 // |
|
1779 void CEikMenuPaneExtension::ConstructMenuSctRowFromDialogL( TDes& aSpecialChars, TInt aResourceId ) |
|
1780 { |
|
1781 TBool renew = EFalse; |
|
1782 if (iSct) |
|
1783 { |
|
1784 delete iSct; |
|
1785 iSct = NULL; |
|
1786 renew = ETrue; |
|
1787 } |
|
1788 iSct = new(ELeave) CAknCharMap(); |
|
1789 iSct->ConstructMenuSctRowFromDialogL(aResourceId); |
|
1790 iSct->SetBuffer( aSpecialChars ); |
|
1791 if ( renew && iMenuPaneWindow && iControl) |
|
1792 { |
|
1793 iSct->SetContainerWindowL( *iControl ); |
|
1794 if ( AknLayoutUtils::PenEnabled() ) |
|
1795 { |
|
1796 iSct->SetGloballyCapturing( ETrue ); |
|
1797 iSct->SetPointerCapture( ETrue ); |
|
1798 } |
|
1799 } |
|
1800 } |
|
1801 |
|
1802 // ----------------------------------------------------------------------------- |
|
1803 // CEikMenuPaneExtension::HandleControlEventL |
|
1804 // ----------------------------------------------------------------------------- |
|
1805 // |
|
1806 void CEikMenuPaneExtension::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEventType) |
|
1807 { |
|
1808 _AKNTRACE_FUNC_ENTER; |
|
1809 if ( AknLayoutUtils::PenEnabled() ) |
|
1810 { |
|
1811 if(aEventType == EEventStateChanged) |
|
1812 { |
|
1813 // Something has been selected from CharMap |
|
1814 iSpecialCharPointed = ETrue; |
|
1815 } |
|
1816 } |
|
1817 _AKNTRACE( "aEventType = %d", aEventType ); |
|
1818 _AKNTRACE_FUNC_EXIT; |
|
1819 } |
|
1820 |
|
1821 |
|
1822 // ----------------------------------------------------------------------------- |
|
1823 // CEikMenuPaneExtension::ImmediateFeedback |
|
1824 // ----------------------------------------------------------------------------- |
|
1825 // |
|
1826 void CEikMenuPaneExtension::ImmediateFeedback( |
|
1827 TTouchLogicalFeedback aType, |
|
1828 TTouchFeedbackType aFbType = TTouchFeedbackType( ETouchFeedbackAudio | |
|
1829 ETouchFeedbackVibra )) |
|
1830 { |
|
1831 if ( iFeedback ) |
|
1832 { |
|
1833 iFeedback->InstantFeedback( iControl, aType, aFbType, TPointerEvent() ); |
|
1834 } |
|
1835 } |
|
1836 |
|
1837 |
|
1838 // ----------------------------------------------------------------------------- |
|
1839 // CEikMenuPaneExtension::PrepareCascadeForItemCommands |
|
1840 // ----------------------------------------------------------------------------- |
|
1841 // |
|
1842 void CEikMenuPaneExtension::PrepareCascadeForItemCommands() |
|
1843 { |
|
1844 if ( iFlags.IsSet( ESingleClickEnabled ) |
|
1845 && iControl->iOwner |
|
1846 && iControl->iOwner->iExtension ) |
|
1847 { |
|
1848 const TBitFlags& ownerFlags( iControl->iOwner->iExtension->iFlags ); |
|
1849 if ( ownerFlags.IsSet( EContextSensitive ) ) |
|
1850 { |
|
1851 iFlags.Set( EContextSensitive ); |
|
1852 } |
|
1853 else if ( ownerFlags.IsSet( EHideItemSpecificCommands ) ) |
|
1854 { |
|
1855 iControl->SetItemCommandsDimmed(); |
|
1856 } |
|
1857 } |
|
1858 } |
|
1859 |
|
1860 |
|
1861 // ----------------------------------------------------------------------------- |
|
1862 // CEikMenuPaneExtension::ContextSensitiveMenu |
|
1863 // ----------------------------------------------------------------------------- |
|
1864 // |
|
1865 TBool CEikMenuPaneExtension::ContextSensitiveMenu() const |
|
1866 { |
|
1867 TBool isContextSensitive( EFalse ); |
|
1868 if ( !iControl->iOwner ) |
|
1869 { |
|
1870 CEikMenuBar* menuBar = static_cast<CEikMenuBar*>( iControl->Parent() ); |
|
1871 if ( menuBar && menuBar->GetMenuType() == CEikMenuBar::EMenuContext ) |
|
1872 { |
|
1873 isContextSensitive = ETrue; |
|
1874 } |
|
1875 } |
|
1876 return isContextSensitive; |
|
1877 } |
|
1878 |
|
1879 |
|
1880 // ----------------------------------------------------------------------------- |
|
1881 // CEikMenuPaneExtension::ItemSpecificCommand |
|
1882 // ----------------------------------------------------------------------------- |
|
1883 // |
|
1884 TBool CEikMenuPaneExtension::ItemSpecificCommand( CEikMenuPaneItem& aItem ) |
|
1885 { |
|
1886 TBool itemSpecific( EFalse ); |
|
1887 if ( ( aItem.iData.iFlags & EEikMenuItemSpecific |
|
1888 || aItem.iData.iFlags & EEikMenuItemSpecificListQuery ) |
|
1889 && !( aItem.iData.iFlags & EEikMenuItemDimmed ) ) |
|
1890 { |
|
1891 itemSpecific = ETrue; |
|
1892 } |
|
1893 return itemSpecific; |
|
1894 } |
|
1895 |
|
1896 |
|
1897 // ----------------------------------------------------------------------------- |
|
1898 // CEikMenuPaneExtension::EnableHighlight |
|
1899 // ----------------------------------------------------------------------------- |
|
1900 // |
|
1901 void CEikMenuPaneExtension::EnableHighlight( |
|
1902 TBool aEnabled, TBool aPointerEnabled ) |
|
1903 { |
|
1904 TBool wasEnabled( iFlags.IsSet( EHighlightEnabled ) ); |
|
1905 if ( aEnabled ) |
|
1906 { |
|
1907 iFlags.Set( EHighlightEnabled ); |
|
1908 } |
|
1909 else |
|
1910 { |
|
1911 iFlags.Clear( EHighlightEnabled ); |
|
1912 } |
|
1913 if ( !aPointerEnabled |
|
1914 && iCba |
|
1915 && ( ( wasEnabled && !aEnabled ) || ( !wasEnabled && aEnabled ) ) ) |
|
1916 { |
|
1917 iCba->MakeCommandVisible( EAknSoftkeySelect, aEnabled ); |
|
1918 } |
|
1919 } |
|
1920 |
|
1921 |
|
1922 // ----------------------------------------------------------------------------- |
|
1923 // CEikMenuPaneExtension::HighlightEnabled |
|
1924 // ----------------------------------------------------------------------------- |
|
1925 // |
|
1926 TBool CEikMenuPaneExtension::HighlightEnabled() |
|
1927 { |
|
1928 return iFlags.IsSet( EHighlightEnabled ); |
|
1929 } |
|
1930 |
|
1931 |
|
1932 // ----------------------------------------------------------------------------- |
|
1933 // CEikMenuPaneExtension::SetDefaultHighlight |
|
1934 // ----------------------------------------------------------------------------- |
|
1935 // |
|
1936 void CEikMenuPaneExtension::SetDefaultHighlight() |
|
1937 { |
|
1938 TInt item( CEikMenuPane::ENothingSelected ); |
|
1939 if ( iSct ) |
|
1940 { |
|
1941 iSctHighlighted = ETrue; |
|
1942 } |
|
1943 else |
|
1944 { |
|
1945 item = iControl->iScroller->TopItemIndex(); |
|
1946 // Partial item |
|
1947 if ( Offset() != 0 ) |
|
1948 { |
|
1949 item++; |
|
1950 } |
|
1951 // Task swapper |
|
1952 TInt taskSwapper; |
|
1953 if ( iControl->MenuItemExists( EAknCmdTaskSwapper, taskSwapper ) ) |
|
1954 { |
|
1955 if ( item == taskSwapper ) |
|
1956 { |
|
1957 item++; |
|
1958 } |
|
1959 } |
|
1960 } |
|
1961 iControl->SetSelectedItem( item ); |
|
1962 EnableHighlight( ETrue ); |
|
1963 if ( iControl->IsVisible() ) |
|
1964 { |
|
1965 iControl->RepaintHighlight(); |
|
1966 } |
|
1967 } |
|
1968 |
|
1969 |
|
1970 // ============================================================================= |
|
1971 // Implementation of CEikMenuPane |
|
1972 // ============================================================================= |
|
1973 |
|
1974 // |
|
1975 // CItemArray |
|
1976 // |
|
1977 |
|
1978 // ----------------------------------------------------------------------------- |
|
1979 // CEikMenuPane::CItemArray::~CItemArray |
|
1980 // ----------------------------------------------------------------------------- |
|
1981 // |
|
1982 EXPORT_C CEikMenuPane::CItemArray::~CItemArray() |
|
1983 { |
|
1984 ResetAndDestroy(); |
|
1985 } |
|
1986 |
|
1987 // ----------------------------------------------------------------------------- |
|
1988 // CEikMenuPane::CItemArray::CItemArray |
|
1989 // ----------------------------------------------------------------------------- |
|
1990 // |
|
1991 EXPORT_C CEikMenuPane::CItemArray::CItemArray() |
|
1992 : CArrayPtrFlat<CEikMenuPaneItem>( KItemGranularity ) |
|
1993 { |
|
1994 __DECLARE_NAME(_S( "CEikMenuPane::CItemArray") ); |
|
1995 } |
|
1996 |
|
1997 // ----------------------------------------------------------------------------- |
|
1998 // CEikMenuPane::CItemArray::AddItemL |
|
1999 // Adds the menu pane item aMenuItem to the end of the array owned by the menu pane |
|
2000 // and transfers ownership. |
|
2001 // ----------------------------------------------------------------------------- |
|
2002 // |
|
2003 EXPORT_C void CEikMenuPane::CItemArray::AddItemL( CEikMenuPaneItem* aMenuItem ) |
|
2004 { |
|
2005 CleanupStack::PushL( aMenuItem ); |
|
2006 AppendL( aMenuItem ); |
|
2007 CleanupStack::Pop(); |
|
2008 } |
|
2009 |
|
2010 // |
|
2011 // CExtendedItemData |
|
2012 // |
|
2013 |
|
2014 CExtendedItemData::~CExtendedItemData() |
|
2015 { |
|
2016 delete iIcon; |
|
2017 delete iScaleableText; |
|
2018 } |
|
2019 |
|
2020 |
|
2021 // |
|
2022 // CEikMenuPaneItem |
|
2023 // |
|
2024 |
|
2025 // ----------------------------------------------------------------------------- |
|
2026 // CEikMenuPaneItem::CEikMenuPaneItem |
|
2027 // ----------------------------------------------------------------------------- |
|
2028 // |
|
2029 EXPORT_C CEikMenuPaneItem::CEikMenuPaneItem() |
|
2030 { |
|
2031 CreateExtendedDataBlock(); |
|
2032 } |
|
2033 |
|
2034 // ----------------------------------------------------------------------------- |
|
2035 // CEikMenuPaneItem::~CEikMenuPaneItem |
|
2036 // ----------------------------------------------------------------------------- |
|
2037 // |
|
2038 EXPORT_C CEikMenuPaneItem::~CEikMenuPaneItem() |
|
2039 { |
|
2040 delete iExtendedData; |
|
2041 } |
|
2042 |
|
2043 // ----------------------------------------------------------------------------- |
|
2044 // CEikMenuPaneItem::SetIcon |
|
2045 // ----------------------------------------------------------------------------- |
|
2046 // |
|
2047 EXPORT_C void CEikMenuPaneItem::SetIcon( CGulIcon* aIcon ) |
|
2048 { |
|
2049 if ( iExtendedData ) |
|
2050 { |
|
2051 if( iExtendedData->iIcon ) |
|
2052 { |
|
2053 delete iExtendedData->iIcon; |
|
2054 } |
|
2055 |
|
2056 iExtendedData->iIcon = aIcon; |
|
2057 } |
|
2058 } |
|
2059 |
|
2060 // ----------------------------------------------------------------------------- |
|
2061 // CEikMenuPaneItem::DrawItemIcon |
|
2062 // Draws the icon for the item to the graphics context aGc, in the rectangle aRect allocating a square area with |
|
2063 // sides of size of aBitmapSpaceRequired to contain the icon. Draws the icon in a dimmed style if aDimmed is |
|
2064 // ETrue. |
|
2065 // ----------------------------------------------------------------------------- |
|
2066 // |
|
2067 EXPORT_C void CEikMenuPaneItem::DrawItemIcon( CWindowGc& aGc, |
|
2068 TRect aRect, |
|
2069 TBool /*aDimmed*/, |
|
2070 TInt /*aBitmapSpaceRequired*/ ) const |
|
2071 { |
|
2072 _AKNTRACE_FUNC_ENTER; |
|
2073 if (iExtendedData && iExtendedData->iIcon) |
|
2074 { |
|
2075 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
2076 TRect rect( aRect ); |
|
2077 AknIconUtils::SetSize(iExtendedData->iIcon->Bitmap(), rect.Size()); |
|
2078 |
|
2079 TInt rectWidth = rect.Width(); |
|
2080 TInt rectHeight = rect.Height(); |
|
2081 TInt iconWidth = iExtendedData->iIcon->Bitmap()->SizeInPixels().iWidth; |
|
2082 TInt iconHeight = iExtendedData->iIcon->Bitmap()->SizeInPixels().iHeight; |
|
2083 |
|
2084 // If aspect ratio of the image and rect do not match the image |
|
2085 // is centered. |
|
2086 if ( rectWidth > iconWidth ) |
|
2087 { |
|
2088 rect.iTl.iX += TInt( ( rectWidth - iconWidth ) / 2 ); |
|
2089 } |
|
2090 if ( rectHeight > iconHeight ) |
|
2091 { |
|
2092 rect.iTl.iY += TInt( ( rectHeight - iconHeight ) / 2 ); |
|
2093 } |
|
2094 _AKNTRACE( "rectWidth = %d", rectWidth ); |
|
2095 _AKNTRACE( "rectHeight = %d", rectHeight ); |
|
2096 _AKNTRACE( "iconWidth = %d", iconWidth ); |
|
2097 _AKNTRACE( "iconHeight = %d", iconHeight ); |
|
2098 _AKNTRACE( "rect.iTl.iX = %d", rect.iTl.iX ); |
|
2099 _AKNTRACE( "rect.iTl.iY = %d", rect.iTl.iY ); |
|
2100 |
|
2101 aGc.BitBltMasked( rect.iTl, iExtendedData->iIcon->Bitmap(), |
|
2102 TRect(0, 0, rect.Width(), rect.Height()), |
|
2103 iExtendedData->iIcon->Mask(), ETrue); |
|
2104 } |
|
2105 _AKNTRACE_FUNC_EXIT; |
|
2106 } |
|
2107 |
|
2108 // ----------------------------------------------------------------------------- |
|
2109 // CEikMenuPaneItem::CreateIconL |
|
2110 // Constructs a new icon for the item, taking ownership of the picture bitmap |
|
2111 // aBitmap and the mask bitmap aMask unless bitmaps have been set to be owned externally. |
|
2112 // ----------------------------------------------------------------------------- |
|
2113 // |
|
2114 EXPORT_C void CEikMenuPaneItem::CreateIconL( CFbsBitmap* aBitmap, CFbsBitmap* aMask ) |
|
2115 { |
|
2116 if ( iExtendedData ) |
|
2117 { |
|
2118 if( iExtendedData->iIcon ) |
|
2119 { |
|
2120 delete iExtendedData->iIcon; |
|
2121 } |
|
2122 |
|
2123 iExtendedData->iIcon = CGulIcon::NewL( aBitmap, aMask ); |
|
2124 } |
|
2125 } |
|
2126 |
|
2127 /** |
|
2128 * |
|
2129 */ |
|
2130 // ----------------------------------------------------------------------------- |
|
2131 // CEikMenuPaneItem::IconBitmap |
|
2132 // Returns a pointer to the picture bitmap of the item icon. |
|
2133 // Does not normally imply transfer of ownership. |
|
2134 // ----------------------------------------------------------------------------- |
|
2135 // |
|
2136 EXPORT_C CFbsBitmap* CEikMenuPaneItem::IconBitmap() const |
|
2137 { |
|
2138 if ( iExtendedData ) |
|
2139 { |
|
2140 return iExtendedData->iIcon ? iExtendedData->iIcon->Bitmap() : NULL; |
|
2141 } |
|
2142 |
|
2143 return NULL; |
|
2144 } |
|
2145 |
|
2146 |
|
2147 // ----------------------------------------------------------------------------- |
|
2148 // CEikMenuPaneItem::IconMask |
|
2149 // Returns a pointer to the mask bitmap of the item icon. |
|
2150 // Does not normally imply transfer of ownership. |
|
2151 // ----------------------------------------------------------------------------- |
|
2152 // |
|
2153 EXPORT_C CFbsBitmap* CEikMenuPaneItem::IconMask() const |
|
2154 { |
|
2155 if ( iExtendedData ) |
|
2156 { |
|
2157 return iExtendedData->iIcon ? iExtendedData->iIcon->Mask() : NULL; |
|
2158 } |
|
2159 |
|
2160 return NULL; |
|
2161 } |
|
2162 |
|
2163 |
|
2164 // ----------------------------------------------------------------------------- |
|
2165 // CEikMenuPaneItem::SetBitmapsOwnedExternally |
|
2166 // Sets the item icon to be owned externally if aOwnedExternally is ETrue. |
|
2167 // ----------------------------------------------------------------------------- |
|
2168 // |
|
2169 EXPORT_C void CEikMenuPaneItem::SetBitmapsOwnedExternally( TBool aOwnedExternally ) |
|
2170 { |
|
2171 if ( iExtendedData ) |
|
2172 { |
|
2173 if( iExtendedData->iIcon ) |
|
2174 { |
|
2175 iExtendedData->iIcon->SetBitmapsOwnedExternally( aOwnedExternally ); |
|
2176 } |
|
2177 } |
|
2178 } |
|
2179 |
|
2180 |
|
2181 // ----------------------------------------------------------------------------- |
|
2182 // CEikMenuPaneItem::SetIconBitmapL |
|
2183 // Sets the picture bitmap for the title icon to aBitmap. |
|
2184 // Transfers ownership unless the bitmaps are owned externally. |
|
2185 // ----------------------------------------------------------------------------- |
|
2186 // |
|
2187 EXPORT_C void CEikMenuPaneItem::SetIconBitmapL( CFbsBitmap* aBitmap ) |
|
2188 { |
|
2189 if ( iExtendedData ) |
|
2190 { |
|
2191 if( !iExtendedData->iIcon ) |
|
2192 { |
|
2193 iExtendedData->iIcon = CGulIcon::NewL(); |
|
2194 } |
|
2195 |
|
2196 iExtendedData->iIcon->SetBitmap( aBitmap ); |
|
2197 } |
|
2198 } |
|
2199 |
|
2200 |
|
2201 // ----------------------------------------------------------------------------- |
|
2202 // CEikMenuPaneItem::SetIconMaskL |
|
2203 // Sets the mask bitmap for the title icon to aMask. |
|
2204 // Transfers ownership unless the bitmaps are owned externally. |
|
2205 // ----------------------------------------------------------------------------- |
|
2206 // |
|
2207 EXPORT_C void CEikMenuPaneItem::SetIconMaskL( CFbsBitmap* aMask ) |
|
2208 { |
|
2209 if ( iExtendedData ) |
|
2210 { |
|
2211 if( !iExtendedData->iIcon ) |
|
2212 { |
|
2213 iExtendedData->iIcon = CGulIcon::NewL(); |
|
2214 } |
|
2215 |
|
2216 iExtendedData->iIcon->SetMask( aMask ); |
|
2217 } |
|
2218 } |
|
2219 |
|
2220 |
|
2221 // ----------------------------------------------------------------------------- |
|
2222 // CEikMenuPaneItem::ScaleableText |
|
2223 // Returns scaleable text. If there isn't scaleable text available |
|
2224 // then this method returns iData.iText. |
|
2225 // ----------------------------------------------------------------------------- |
|
2226 // |
|
2227 EXPORT_C TPtrC CEikMenuPaneItem::ScaleableText() const |
|
2228 { |
|
2229 if ( ( iExtendedData ) && ( iExtendedData->iScaleableText ) ) |
|
2230 { |
|
2231 return iExtendedData->iScaleableText->Des(); |
|
2232 } |
|
2233 |
|
2234 return iData.iText; |
|
2235 } |
|
2236 |
|
2237 |
|
2238 // ----------------------------------------------------------------------------- |
|
2239 // CEikMenuPaneItem::SetScaleableTextL |
|
2240 // Sets scaleable text. iData.iText is set to first text version. |
|
2241 // ----------------------------------------------------------------------------- |
|
2242 // |
|
2243 EXPORT_C void CEikMenuPaneItem::SetScaleableTextL( const TDesC& aText ) |
|
2244 { |
|
2245 if ( iExtendedData ) |
|
2246 { |
|
2247 if ( iExtendedData->iScaleableText ) |
|
2248 { |
|
2249 delete iExtendedData->iScaleableText; |
|
2250 iExtendedData->iScaleableText = NULL; |
|
2251 } |
|
2252 |
|
2253 iData.iText = GetNominalText( aText ); |
|
2254 |
|
2255 if ( IsScaleableText( aText ) ) |
|
2256 { |
|
2257 iExtendedData->iScaleableText = HBufC::NewL( aText.Length() ); |
|
2258 iExtendedData->iScaleableText->Des().Copy( aText ); |
|
2259 } |
|
2260 } |
|
2261 } |
|
2262 |
|
2263 |
|
2264 // ----------------------------------------------------------------------------- |
|
2265 // CEikMenuPaneItem::GetNominalText |
|
2266 // ----------------------------------------------------------------------------- |
|
2267 // |
|
2268 TPtrC CEikMenuPaneItem::GetNominalText( const TDesC& aText ) |
|
2269 { |
|
2270 TInt limit = aText.Length(); |
|
2271 TInt border = aText.Locate( TChar( KScaleableTextSeparator ) ); |
|
2272 if ( border != KErrNotFound ) |
|
2273 { |
|
2274 limit = border; |
|
2275 } |
|
2276 |
|
2277 limit = ( limit > CEikMenuPaneItem::SData::ENominalTextLength ? CEikMenuPaneItem::SData::ENominalTextLength : limit ); |
|
2278 |
|
2279 return aText.Left( limit); |
|
2280 } |
|
2281 |
|
2282 |
|
2283 |
|
2284 // |
|
2285 // class CEikMenuPane |
|
2286 // |
|
2287 |
|
2288 // ----------------------------------------------------------------------------- |
|
2289 // CEikMenuPane::~CEikMenuPane |
|
2290 // ----------------------------------------------------------------------------- |
|
2291 // |
|
2292 EXPORT_C CEikMenuPane::~CEikMenuPane() |
|
2293 { |
|
2294 _AKNTRACE_FUNC_ENTER; |
|
2295 AKNTASHOOK_REMOVE(); |
|
2296 CloseCascadeMenu(); |
|
2297 if ( !ItemArrayOwnedExternally() ) |
|
2298 { |
|
2299 delete iItemArray; |
|
2300 iItemArray = NULL; |
|
2301 } |
|
2302 else |
|
2303 { |
|
2304 ResetItemArray(); |
|
2305 } |
|
2306 |
|
2307 if ( iLaunchingButton ) |
|
2308 { |
|
2309 TPointerEvent event; |
|
2310 event.iType = TPointerEvent::EButton1Up; |
|
2311 event.iModifiers = 0; |
|
2312 event.iPosition = iLaunchingButton->Position(); |
|
2313 TRAP_IGNORE( iLaunchingButton->HandlePointerEventL( event ) ); |
|
2314 iLaunchingButton = NULL; // not owned |
|
2315 } |
|
2316 |
|
2317 delete iScroller; |
|
2318 iScroller = NULL; |
|
2319 |
|
2320 delete iSBFrame; |
|
2321 iSBFrame = NULL; |
|
2322 |
|
2323 iMenuObserver = NULL; // not owned |
|
2324 |
|
2325 iEditMenuObserver = NULL; // not owned |
|
2326 |
|
2327 iOwner = NULL; // not owned |
|
2328 |
|
2329 delete iExtension; |
|
2330 iExtension = NULL; |
|
2331 _AKNTRACE_FUNC_EXIT; |
|
2332 } |
|
2333 |
|
2334 // ----------------------------------------------------------------------------- |
|
2335 // CEikMenuPane::CEikMenuPane |
|
2336 // ----------------------------------------------------------------------------- |
|
2337 // |
|
2338 EXPORT_C CEikMenuPane::CEikMenuPane( MEikMenuObserver* aMenuObserver ) |
|
2339 : iMenuObserver( aMenuObserver ) |
|
2340 { |
|
2341 _AKNTRACE_FUNC_ENTER; |
|
2342 __ASSERT_DEBUG( iMenuObserver,Panic( EEikPanicNullPointer ) ); |
|
2343 __DECLARE_NAME(_S("CEikMenuPane")); |
|
2344 iBorder = TGulBorder( AknBorderId::EAknBorderMenuSubmenuPopup ); // AKNLAF |
|
2345 iAllowPointerUpEvents = EFalse; |
|
2346 iNumberOfDragEvents = 0; |
|
2347 MakeVisible( EFalse ); |
|
2348 AKNTASHOOK_ADD( this, "CEikMenuPane" ); |
|
2349 _AKNTRACE_FUNC_EXIT; |
|
2350 } |
|
2351 |
|
2352 // ----------------------------------------------------------------------------- |
|
2353 // CEikMenuPane::ConstructL |
|
2354 // ----------------------------------------------------------------------------- |
|
2355 // |
|
2356 EXPORT_C void CEikMenuPane::ConstructL( CEikMenuPane* aOwner, MEikMenuObserver* aEditMenuObserver ) |
|
2357 { |
|
2358 _AKNTRACE_FUNC_ENTER; |
|
2359 iOwner = aOwner; |
|
2360 iEditMenuObserver = aEditMenuObserver; |
|
2361 |
|
2362 CheckCreateScrollerL(); |
|
2363 CheckCreateExtensionL(); |
|
2364 |
|
2365 iExtension->iTransitionsOn = FeatureManager::FeatureSupported( KFeatureIdUiTransitionEffects ); |
|
2366 |
|
2367 CreateWindowL( iCoeEnv->RootWin() ); |
|
2368 EnableWindowTransparency(); |
|
2369 SetAllowStrayPointers(); |
|
2370 EnableDragEvents(); |
|
2371 |
|
2372 TAknWindowLineLayout menuLineLayout; |
|
2373 if ( iOwner ) // submenu |
|
2374 { |
|
2375 menuLineLayout = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( 0 ).LayoutLine(); |
|
2376 } |
|
2377 else |
|
2378 { |
|
2379 menuLineLayout = AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine(); |
|
2380 } |
|
2381 |
|
2382 TRect windowRect = Rect(); |
|
2383 TAknLayoutRect menuLayoutRect; |
|
2384 menuLayoutRect.LayoutRect( windowRect, menuLineLayout ); |
|
2385 iItemHeight = menuLayoutRect.Rect().Height(); |
|
2386 |
|
2387 if ( iExtension->iSct ) |
|
2388 { |
|
2389 RWindow* window = (RWindow*)this->DrawableWindow(); |
|
2390 iExtension->iMenuPaneWindow = window; |
|
2391 iExtension->iSct->SetContainerWindowL( *this ); |
|
2392 |
|
2393 if ( AknLayoutUtils::PenEnabled() ) |
|
2394 { |
|
2395 // This is effectively the same as CCoeControl::EnableDragEvents() |
|
2396 // which is protected. |
|
2397 window->PointerFilter( EPointerFilterDrag, 0 ); |
|
2398 iExtension->iSct->SetGloballyCapturing( ETrue ); |
|
2399 iExtension->iSct->SetPointerCapture( ETrue ); |
|
2400 iExtension->iSct->SetObserver(iExtension); |
|
2401 } |
|
2402 } |
|
2403 |
|
2404 if ( iOwner ) // submenu |
|
2405 { |
|
2406 SetPointerCapture( ETrue ); |
|
2407 } |
|
2408 |
|
2409 LoadCascadeBitmapL(); |
|
2410 LoadCheckMarkBitmapL(); |
|
2411 LoadRadioButtonBitmapL(); |
|
2412 |
|
2413 // Window may not be created if OOM earlier during construction |
|
2414 RWindow* window = &Window(); |
|
2415 if( window == NULL ) |
|
2416 User::Leave( KErrNoMemory ); |
|
2417 |
|
2418 Window().SetOrdinalPosition( 0 ); |
|
2419 |
|
2420 Window().SetPointerGrab( ETrue ); |
|
2421 SetGloballyCapturing( ETrue ); |
|
2422 |
|
2423 iExtension->iPhysics->UpdateViewWindowControl(); |
|
2424 _AKNTRACE_FUNC_EXIT; |
|
2425 } |
|
2426 |
|
2427 |
|
2428 // ----------------------------------------------------------------------------- |
|
2429 // CEikMenuPane::ConstructFromResourceL |
|
2430 // Constructs the menu pane using the resource reader aReader, filling the menu item array with the |
|
2431 // list of menu items provided by the resource file. |
|
2432 // ----------------------------------------------------------------------------- |
|
2433 // |
|
2434 EXPORT_C void CEikMenuPane::ConstructFromResourceL( TResourceReader& aReader ) |
|
2435 { |
|
2436 if ( iItemArray && !ItemArrayOwnedExternally() ) |
|
2437 { |
|
2438 delete iItemArray; |
|
2439 iItemArray = NULL; |
|
2440 } |
|
2441 CreateItemArrayL(); |
|
2442 |
|
2443 TAknWindowLineLayout menuLineLayout; |
|
2444 if ( iOwner ) // submenu |
|
2445 { |
|
2446 menuLineLayout = AKN_LAYOUT_WINDOW_list_single_popup_submenu_pane( 0, 0 ); |
|
2447 } |
|
2448 else |
|
2449 { |
|
2450 menuLineLayout = AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( 0 ); |
|
2451 } |
|
2452 TRect windowRect = Rect(); |
|
2453 TAknLayoutRect menuLayoutRect; |
|
2454 menuLayoutRect.LayoutRect( windowRect, menuLineLayout ); |
|
2455 iItemHeight = menuLayoutRect.Rect().Height(); |
|
2456 |
|
2457 CheckCreateScrollerL(); |
|
2458 CheckCreateExtensionL(); |
|
2459 |
|
2460 const TInt count=aReader.ReadInt16(); |
|
2461 for ( TInt ii=0; ii<count; ++ii ) |
|
2462 { |
|
2463 CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem(); |
|
2464 CleanupStack::PushL( item ); |
|
2465 item->iData.iCommandId = aReader.ReadInt32(); |
|
2466 item->iData.iCascadeId = aReader.ReadInt32(); |
|
2467 item->iData.iFlags = aReader.ReadInt32(); |
|
2468 TPtrC txtptr = aReader.ReadTPtrC(); |
|
2469 item->SetScaleableTextL( txtptr ); |
|
2470 TPtrC extratxtptr = aReader.ReadTPtrC(); |
|
2471 item->iData.iExtraText = extratxtptr; |
|
2472 CreateIconFromResourceL( aReader, *item ); |
|
2473 CleanupStack::Pop(); // pop first, since additem pushes again |
|
2474 iItemArray->AddItemL( item ); |
|
2475 aReader.ReadInt32(); // extension link |
|
2476 |
|
2477 if ( item->iData.iFlags&( EEikMenuItemRadioStart|EEikMenuItemRadioMiddle|EEikMenuItemRadioEnd ) ) |
|
2478 { |
|
2479 iExtension->iHasRadioGroup = ETrue; |
|
2480 if ( item->iData.iFlags&EEikMenuItemSymbolOn ) |
|
2481 { |
|
2482 iExtension->iSelectedRadioButtonItem = ii; |
|
2483 } |
|
2484 } |
|
2485 } |
|
2486 |
|
2487 aReader.ReadInt32(); // extension link |
|
2488 } |
|
2489 |
|
2490 // ----------------------------------------------------------------------------- |
|
2491 // CEikMenuPane::AddMenuItemsL |
|
2492 // ----------------------------------------------------------------------------- |
|
2493 // |
|
2494 EXPORT_C void CEikMenuPane::AddMenuItemsL( TInt aResourceId, TInt aPreviousId, TBool /*aAddSeperator*/ ) |
|
2495 { |
|
2496 if ( !iItemArray ) |
|
2497 { |
|
2498 CreateItemArrayL(); |
|
2499 } |
|
2500 |
|
2501 // Read from resource and add items after the item with 'aPreviousId' |
|
2502 TResourceReader reader; |
|
2503 iEikonEnv->CreateResourceReaderLC( reader, aResourceId ); |
|
2504 |
|
2505 TInt position = iItemArray->Count(); |
|
2506 if ( aPreviousId ) |
|
2507 { |
|
2508 ItemAndPos( aPreviousId, position ); |
|
2509 position++; |
|
2510 } |
|
2511 |
|
2512 // 'Active Applications' menu item is forced to be first |
|
2513 // item in the options menu. |
|
2514 if (aResourceId == R_AVKON_MENUPANE_TASK_SWAPPER) |
|
2515 { |
|
2516 position = 0; |
|
2517 } |
|
2518 |
|
2519 const TInt count = reader.ReadInt16(); |
|
2520 for (TInt ii = 0; ii < count; ++ii) |
|
2521 { |
|
2522 CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem(); |
|
2523 CleanupStack::PushL( item ); |
|
2524 item->iData.iCommandId = reader.ReadInt32(); |
|
2525 item->iData.iCascadeId = reader.ReadInt32(); |
|
2526 item->iData.iFlags = reader.ReadInt32(); |
|
2527 TPtrC txtptr = reader.ReadTPtrC(); |
|
2528 item->SetScaleableTextL( txtptr ); |
|
2529 TPtrC extratxtptr = reader.ReadTPtrC(); |
|
2530 item->iData.iExtraText = extratxtptr; |
|
2531 CreateIconFromResourceL( reader, *item ); |
|
2532 iItemArray->InsertL( position++, item ); |
|
2533 reader.ReadInt32(); // extension link |
|
2534 CleanupStack::Pop(); |
|
2535 |
|
2536 if ( item->iData.iFlags&(EEikMenuItemRadioStart|EEikMenuItemRadioMiddle|EEikMenuItemRadioEnd) ) |
|
2537 { |
|
2538 iExtension->iHasRadioGroup = ETrue; |
|
2539 if ( item->iData.iFlags&EEikMenuItemSymbolOn ) |
|
2540 { |
|
2541 iExtension->iSelectedRadioButtonItem = ii; // so if there are several on, we have only the last of them to be activated |
|
2542 } |
|
2543 } |
|
2544 } |
|
2545 CleanupStack::PopAndDestroy();// reader |
|
2546 } |
|
2547 |
|
2548 // ----------------------------------------------------------------------------- |
|
2549 // CEikMenuPane::FilterDimmedItems |
|
2550 // ----------------------------------------------------------------------------- |
|
2551 // |
|
2552 void CEikMenuPane::FilterDimmedItems() |
|
2553 { |
|
2554 TInt pos = iItemArray->Count() - 1; |
|
2555 while ( pos >= 0 ) |
|
2556 { |
|
2557 CEikMenuPaneItem* item = (*iItemArray)[pos]; |
|
2558 if ( item->iData.iFlags&EEikMenuItemDimmed ) |
|
2559 { |
|
2560 DeleteMenuItem( item->iData.iCommandId ); |
|
2561 } |
|
2562 pos--; |
|
2563 } |
|
2564 } |
|
2565 |
|
2566 |
|
2567 // ----------------------------------------------------------------------------- |
|
2568 // CEikMenuPane::SetScrollBarOnLeft |
|
2569 // Sets the scroll bar to occupy the left side of the menu pane if aOnLeft is ETrue |
|
2570 // |
|
2571 // @since ER5U |
|
2572 // ----------------------------------------------------------------------------- |
|
2573 // |
|
2574 EXPORT_C void CEikMenuPane::SetScrollBarOnLeft(TBool aOnLeft) |
|
2575 { |
|
2576 if ( aOnLeft ) |
|
2577 { |
|
2578 iFlags |= EEikMenuItemScrollBarLeft; |
|
2579 } |
|
2580 else |
|
2581 { |
|
2582 iFlags &= (~EEikMenuItemScrollBarLeft); |
|
2583 } |
|
2584 } |
|
2585 |
|
2586 |
|
2587 // ----------------------------------------------------------------------------- |
|
2588 // CEikMenuPane::SetArrowHeadScrollBar |
|
2589 // Sets the menu pane to use an arrow head scroll bar if aArrowHead is ETrue. |
|
2590 // |
|
2591 // @since ER5U |
|
2592 // ----------------------------------------------------------------------------- |
|
2593 // |
|
2594 EXPORT_C void CEikMenuPane::SetArrowHeadScrollBar( TBool /*aArrowHead*/ ) |
|
2595 { |
|
2596 } |
|
2597 |
|
2598 |
|
2599 // ----------------------------------------------------------------------------- |
|
2600 // CEikMenuPane::ResetItemArray |
|
2601 // Resets the menu's array of items and destroys its elements. |
|
2602 // |
|
2603 // @since ER5U |
|
2604 // ----------------------------------------------------------------------------- |
|
2605 // |
|
2606 void CEikMenuPane::ResetItemArray() |
|
2607 { |
|
2608 if ( !iItemArray ) |
|
2609 { |
|
2610 return; |
|
2611 } |
|
2612 iItemArray->ResetAndDestroy(); |
|
2613 } |
|
2614 |
|
2615 // ----------------------------------------------------------------------------- |
|
2616 // CEikMenuPane::CreateItemArrayL |
|
2617 // Creates a new item array to be owned by the menu pane. |
|
2618 // |
|
2619 // @since ER5U |
|
2620 // ----------------------------------------------------------------------------- |
|
2621 // |
|
2622 void CEikMenuPane::CreateItemArrayL() |
|
2623 { |
|
2624 iItemArray = new(ELeave) CItemArray; |
|
2625 } |
|
2626 |
|
2627 // ----------------------------------------------------------------------------- |
|
2628 // CEikMenuPane::CreateIconFromResourceL |
|
2629 // Creates an icon for the menu item aItem using the resource reader aReader. |
|
2630 // |
|
2631 // @since ER5U |
|
2632 // ----------------------------------------------------------------------------- |
|
2633 // |
|
2634 void CEikMenuPane::CreateIconFromResourceL( TResourceReader& aReader, CEikMenuPaneItem& aItem ) const |
|
2635 { |
|
2636 TPtrC bitmapFile = aReader.ReadTPtrC(); |
|
2637 TInt bitmapId = aReader.ReadInt16(); |
|
2638 TInt bitmapMaskId = aReader.ReadInt16(); |
|
2639 if ( bitmapId != -1 ) |
|
2640 { |
|
2641 CFbsBitmap* bitmap = NULL; |
|
2642 CFbsBitmap* bitmapMask = NULL; |
|
2643 |
|
2644 if ( bitmapId == EMbmAvkonQgn_indi_app_open_add ) |
|
2645 { |
|
2646 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
2647 AknsUtils::CreateIconLC(skin, |
|
2648 KAknsIIDQgnIndiAppOpen, |
|
2649 bitmap, bitmapMask, |
|
2650 bitmapFile, |
|
2651 bitmapId, bitmapMaskId); |
|
2652 } |
|
2653 else |
|
2654 { |
|
2655 AknIconUtils::CreateIconLC(bitmap, bitmapMask, |
|
2656 bitmapFile, |
|
2657 bitmapId, bitmapMaskId); |
|
2658 } |
|
2659 |
|
2660 aItem.CreateIconL(bitmap, bitmapMask); |
|
2661 CleanupStack::Pop(2); // bitmap, bitmapMask. |
|
2662 } |
|
2663 } |
|
2664 |
|
2665 |
|
2666 // ----------------------------------------------------------------------------- |
|
2667 // CEikMenuPane::Reset |
|
2668 // Destroys the menu pane's item array and scroll bar frame. |
|
2669 // ----------------------------------------------------------------------------- |
|
2670 // |
|
2671 EXPORT_C void CEikMenuPane::Reset() |
|
2672 { |
|
2673 delete iItemArray; |
|
2674 iItemArray = NULL; |
|
2675 delete iSBFrame; |
|
2676 iSBFrame = NULL; |
|
2677 } |
|
2678 |
|
2679 |
|
2680 // ----------------------------------------------------------------------------- |
|
2681 // CEikMenuPane::CloseCascadeMenu |
|
2682 // Closes and destroys any current cascade menu and takes focus back. |
|
2683 // Does nothing if no cascade menu exists. |
|
2684 // ----------------------------------------------------------------------------- |
|
2685 // |
|
2686 EXPORT_C void CEikMenuPane::CloseCascadeMenu() |
|
2687 { |
|
2688 CloseCascadeMenu( EFalse ); |
|
2689 } |
|
2690 |
|
2691 // ----------------------------------------------------------------------------- |
|
2692 // CEikMenuPane::TryLaunchCascadeMenuL |
|
2693 // ----------------------------------------------------------------------------- |
|
2694 // |
|
2695 void CEikMenuPane::TryLaunchCascadeMenuL(const CEikMenuPaneItem& aItem) |
|
2696 { |
|
2697 _AKNTRACE_FUNC_ENTER; |
|
2698 iExtension->iShowCascadeTransition = EFalse; |
|
2699 iExtension->iButtonDownItem = KErrNotFound; |
|
2700 if ( aItem.iData.iFlags&EEikMenuItemDimmed ) |
|
2701 { |
|
2702 iMenuObserver->HandleAttemptDimmedSelectionL( aItem.iData.iCommandId ); |
|
2703 return; |
|
2704 } |
|
2705 LaunchCascadeMenuL( aItem.iData.iCascadeId ); |
|
2706 _AKNTRACE_FUNC_EXIT; |
|
2707 } |
|
2708 |
|
2709 // ----------------------------------------------------------------------------- |
|
2710 // CEikMenuPane::LaunchCascadeMenuL |
|
2711 // ----------------------------------------------------------------------------- |
|
2712 // |
|
2713 void CEikMenuPane::LaunchCascadeMenuL( TInt aCascadeMenuId ) |
|
2714 { |
|
2715 _AKNTRACE_FUNC_ENTER; |
|
2716 #ifdef THIS_IS_CORRECT_CODE_BUT_DISABLED_BECAUSE_OF_TEST_APPS |
|
2717 // Series 60 does not have cascade options menus from another cascade menus.. |
|
2718 if ( iOwner ) return; |
|
2719 #endif // THIS_IS_CORRECT_CODE_BUT_DISABLED_BECAUSE_OF_TEST_APPS |
|
2720 |
|
2721 TInt err( KErrNone ); |
|
2722 TRAP( err, iCascadeMenuPane = new(ELeave) CEikMenuPane( iMenuObserver )); |
|
2723 iCascadeMenuPane->SetMopParent( this ); |
|
2724 iCascadeMenuPane->SetObserver( Observer() ); |
|
2725 |
|
2726 // delete object here so that new cascade menu pane does not get the same |
|
2727 // address -> messes up transition registration.. |
|
2728 if( iExtension->iCascadeMenuObject ) |
|
2729 { |
|
2730 GfxTransEffect::Deregister( iExtension->iCascadeMenuObject ); |
|
2731 } |
|
2732 |
|
2733 delete iExtension->iCascadeMenuObject; |
|
2734 iExtension->iCascadeMenuObject = NULL; |
|
2735 |
|
2736 User::LeaveIfError( err ); |
|
2737 |
|
2738 // register cascade options menu |
|
2739 GfxTransEffect::Register( iCascadeMenuPane, KGfxOptionsMenuCascadeControlUid, EFalse ); |
|
2740 TRAP( err, DoLaunchCascadeMenuL( aCascadeMenuId ) ); |
|
2741 if ( err ) |
|
2742 { |
|
2743 CloseCascadeMenu(); |
|
2744 User::Leave( err ); |
|
2745 } |
|
2746 _AKNTRACE_FUNC_EXIT; |
|
2747 } |
|
2748 |
|
2749 // ----------------------------------------------------------------------------- |
|
2750 // CEikMenuPane::DoLaunchCascadeMenuL |
|
2751 // ----------------------------------------------------------------------------- |
|
2752 // |
|
2753 void CEikMenuPane::DoLaunchCascadeMenuL( TInt aCascadeMenuId ) |
|
2754 { |
|
2755 _AKNTRACE_FUNC_ENTER; |
|
2756 if ( !iItemArray || iItemArray->Count() == 0 ) |
|
2757 { |
|
2758 return; |
|
2759 } |
|
2760 iCascadeMenuPane->ConstructL( this, iEditMenuObserver ); |
|
2761 iCascadeMenuPane->SetSelectedItem( 0 ); |
|
2762 |
|
2763 // Stop menu pane physics when launching cascade menu |
|
2764 iExtension->iPhysics->StopPhysics(); |
|
2765 iExtension->iPhysics->ResetFriction(); |
|
2766 |
|
2767 iMenuObserver->RestoreMenuL(iCascadeMenuPane,aCascadeMenuId,MEikMenuObserver::EMenuPane); |
|
2768 MEikMenuObserver* fepMenuObserver = CAknEnv::Static()->FepMenuObserver(); |
|
2769 if (fepMenuObserver) |
|
2770 { |
|
2771 fepMenuObserver->DynInitMenuPaneL( aCascadeMenuId, iCascadeMenuPane ); |
|
2772 } |
|
2773 if (iEditMenuObserver) |
|
2774 { |
|
2775 iEditMenuObserver->DynInitMenuPaneL( aCascadeMenuId, iCascadeMenuPane ); |
|
2776 } |
|
2777 |
|
2778 iCascadeMenuPane->iExtension->PrepareCascadeForItemCommands(); |
|
2779 iCascadeMenuPane->iExtension->EnableHighlight( EFalse ); |
|
2780 iCascadeMenuPane->FilterDimmedItems(); |
|
2781 |
|
2782 // cascade menu launch animation |
|
2783 if ( iExtension->iRedirectionListener ) |
|
2784 { |
|
2785 iExtension->iRedirectionListener->LaunchCascadeMenu(); |
|
2786 } |
|
2787 else |
|
2788 { |
|
2789 iExtension->StartCascadeMenuAppearTransition(); |
|
2790 } |
|
2791 |
|
2792 if( AknLayoutUtils::PenEnabled() ) |
|
2793 { |
|
2794 TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp; |
|
2795 if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) |
|
2796 { |
|
2797 fbLogicalType = ETouchFeedbackIncreasingPopUp; |
|
2798 } |
|
2799 iExtension->ImmediateFeedback( fbLogicalType, |
|
2800 ETouchFeedbackVibra ); |
|
2801 } |
|
2802 _AKNTRACE_FUNC_EXIT; |
|
2803 } |
|
2804 |
|
2805 // ----------------------------------------------------------------------------- |
|
2806 // CEikMenuPane::CalculateSizeAndPosition |
|
2807 // Calculates and returns the menu pane's size. |
|
2808 // Also sets the rectangle of the menu pane. |
|
2809 // ----------------------------------------------------------------------------- |
|
2810 // |
|
2811 TRect CEikMenuPane::CalculateSizeAndPosition() |
|
2812 { |
|
2813 _AKNTRACE_FUNC_ENTER; |
|
2814 TRect retVal; |
|
2815 |
|
2816 TInt numItemsInPane = 0; |
|
2817 if ( iItemArray ) |
|
2818 {// Min size is for 1 item even if menu is empty |
|
2819 numItemsInPane = iItemArray->Count(); |
|
2820 } |
|
2821 |
|
2822 if ( iExtension->iSct ) |
|
2823 { |
|
2824 numItemsInPane++; |
|
2825 } |
|
2826 |
|
2827 TInt maxNumItemsInMenu = AknLayoutScalable_Avkon:: |
|
2828 list_single_pane_cp2_ParamLimits().LastRow() + 1; |
|
2829 TInt maxNumItemsInSubMenu = AknLayoutScalable_Avkon:: |
|
2830 list_single_popup_submenu_pane_ParamLimits().LastRow() + 1; |
|
2831 |
|
2832 TInt maxItemsInView = NumberOfItemsThatFitInView(); |
|
2833 |
|
2834 if (iExtension && iExtension->iSct) |
|
2835 { |
|
2836 maxItemsInView++; |
|
2837 } |
|
2838 |
|
2839 numItemsInPane = Min( Max( 1, numItemsInPane ), maxItemsInView); |
|
2840 |
|
2841 TRect windowRect; |
|
2842 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, windowRect ); |
|
2843 |
|
2844 retVal = CalculateSizeAndPositionScalable( windowRect, numItemsInPane ); |
|
2845 _AKNTRACE_FUNC_EXIT; |
|
2846 return retVal; |
|
2847 } |
|
2848 |
|
2849 // ----------------------------------------------------------------------------- |
|
2850 // CEikMenuPane::StartDisplayingMenuPane |
|
2851 // ----------------------------------------------------------------------------- |
|
2852 // |
|
2853 EXPORT_C void CEikMenuPane::StartDisplayingMenuPane( const CEikHotKeyTable* /*aHotKeyTable*/, |
|
2854 const TPoint& /*aTargetPos*/, |
|
2855 const CEikMenuPaneTitle* /*aMenuPaneTitle*/, |
|
2856 TInt /*aMinTitleWidth*/, |
|
2857 TPopupTargetPosType /*aTargetType*/ ) |
|
2858 { |
|
2859 _AKNTRACE_FUNC_ENTER; |
|
2860 if ( iExtension->iRedirectionListener ) |
|
2861 { |
|
2862 iExtension->iRedirectionListener->AppearTransitionStarting(); |
|
2863 } |
|
2864 |
|
2865 CreateScrollBarFrame(); |
|
2866 |
|
2867 iExtension->iPressedDown = EFalse; |
|
2868 iExtension->SetOffset( 0 ); |
|
2869 iExtension->iHasIcon = MenuHasIcon(); |
|
2870 |
|
2871 if ( iExtension->iTransitionsOn ) |
|
2872 { |
|
2873 CAknTransitionUtils::SetAllParents( this ); |
|
2874 } |
|
2875 |
|
2876 const TSize screenSize( iEikonEnv->EikAppUi()->ApplicationRect().Size() ); |
|
2877 |
|
2878 CEikCba *cba = 0; |
|
2879 MopGetObject(cba); |
|
2880 if ( cba ) |
|
2881 { |
|
2882 cba->SetSkinBackgroundId( KAknsIIDQsnBgAreaControlPopup ); |
|
2883 } |
|
2884 |
|
2885 iScroller->SetTopItemIndex(0); // to avoid broken values of topitemindex |
|
2886 |
|
2887 // set highlight visible if menu was opened via HW keys |
|
2888 if ( iCoeEnv->LastEvent().Type() == EEventKey |
|
2889 && iCoeEnv->LastEvent().Key() |
|
2890 && iCoeEnv->LastEvent().Key()->iCode == EKeyCBA1 ) |
|
2891 { |
|
2892 SetDefaultHighlight(); |
|
2893 } |
|
2894 |
|
2895 TRect rect( CalculateSizeAndPosition() ); |
|
2896 TPoint newPos( rect.iTl ); |
|
2897 TSize menuSize( rect.Size() ); |
|
2898 |
|
2899 SetExtent( newPos, menuSize ); |
|
2900 |
|
2901 // We need to set the background context when calling create for the |
|
2902 // first time. Otherwise iExtension->iBgContext would have tiny |
|
2903 // rectangles and grabbing the highlight background would produce |
|
2904 // white. |
|
2905 UpdateBackgroundContext( Rect() ); |
|
2906 |
|
2907 // The extent has been set. This is the first safe point in code to |
|
2908 // construct animations (because before this highlight related layout code |
|
2909 // will produce invalid results |
|
2910 if( iExtension ) |
|
2911 { |
|
2912 // Creates animation only if it does not exist |
|
2913 iExtension->CreateAnimation(); |
|
2914 } |
|
2915 |
|
2916 // Initialize physics engine |
|
2917 TRAP_IGNORE ( iExtension->InitPhysicsL() ); |
|
2918 |
|
2919 MakeVisible(ETrue); |
|
2920 SetFocus(ETrue); |
|
2921 Window().SetPointerGrab( ETrue ); |
|
2922 |
|
2923 if ( iExtension->iSct ) |
|
2924 { |
|
2925 iExtension->iSctHighlighted = ETrue; |
|
2926 iSelectedItem = ENothingSelected; |
|
2927 // If SCT row existing, set the default focus on SCT row not the top |
|
2928 } |
|
2929 |
|
2930 if (iSelectedItem != ENothingSelected) |
|
2931 { |
|
2932 ScrollToMakeItemVisible(iSelectedItem); |
|
2933 } |
|
2934 PrepareHighlightFrame(); |
|
2935 SetCascadedIconSize(); |
|
2936 TRAP_IGNORE( ActivateL()); |
|
2937 if (iMenuPaneTitle) |
|
2938 { |
|
2939 CONST_CAST(CEikMenuPaneTitle*,iMenuPaneTitle)->MakeVisible(ETrue); |
|
2940 TRAP_IGNORE( CONST_CAST(CEikMenuPaneTitle*,iMenuPaneTitle)->ActivateL()); |
|
2941 iMenuPaneTitle->DrawNow(); |
|
2942 } |
|
2943 |
|
2944 TRAP_IGNORE( DoUpdateScrollBarL() ); |
|
2945 |
|
2946 // No highlight - hide softkey |
|
2947 if ( iExtension && iExtension->iCba ) |
|
2948 { |
|
2949 iExtension->iCba->MakeCommandVisible( EAknSoftkeySelect, |
|
2950 iExtension->iFlags.IsSet( |
|
2951 CEikMenuPaneExtension::EHighlightEnabled ) ); |
|
2952 } |
|
2953 |
|
2954 _AKNTRACE_FUNC_EXIT; |
|
2955 } |
|
2956 |
|
2957 |
|
2958 // ----------------------------------------------------------------------------- |
|
2959 // CEikMenuPane::UpdateBackgroundContext |
|
2960 // ----------------------------------------------------------------------------- |
|
2961 // |
|
2962 void CEikMenuPane::UpdateBackgroundContext( const TRect& aWindowRect ) |
|
2963 { |
|
2964 _AKNTRACE_FUNC_ENTER; |
|
2965 TAknLayoutRect topLeft; |
|
2966 TAknLayoutRect bottomRight; |
|
2967 TAknsItemID frameIID; |
|
2968 TAknsItemID frameCenterIID; |
|
2969 |
|
2970 TRect backgroundRect( iExtension->GetBackgroundRect( aWindowRect ) ); |
|
2971 |
|
2972 if( iOwner ) //for sub menu |
|
2973 { |
|
2974 topLeft.LayoutRect( aWindowRect, SkinLayout::Submenu_skin_placing_Line_2() ); |
|
2975 bottomRight.LayoutRect( aWindowRect, SkinLayout::Submenu_skin_placing_Line_5() ); |
|
2976 frameIID = KAknsIIDQsnFrPopupSub; |
|
2977 frameCenterIID = KAknsIIDQsnFrPopupCenterSubmenu; |
|
2978 } |
|
2979 else |
|
2980 { |
|
2981 topLeft.LayoutRect( backgroundRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_2() ); |
|
2982 bottomRight.LayoutRect( backgroundRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_5() ); |
|
2983 frameIID = KAknsIIDQsnFrPopup; |
|
2984 frameCenterIID = KAknsIIDQsnFrPopupCenterMenu; |
|
2985 } |
|
2986 |
|
2987 TRect outerRect( topLeft.Rect().iTl, bottomRight.Rect().iBr ); |
|
2988 TRect innerRect( topLeft.Rect().iBr, bottomRight.Rect().iTl ); |
|
2989 |
|
2990 if( iExtension ) |
|
2991 { |
|
2992 iExtension->iBgContext->SetFrame( frameIID ); |
|
2993 iExtension->iBgContext->SetCenter( frameCenterIID ); |
|
2994 iExtension->iBgContext->SetFrameRects( outerRect, innerRect ); |
|
2995 } |
|
2996 _AKNTRACE( " outerRect.iTl.iX = %d", outerRect.iTl.iX ); |
|
2997 _AKNTRACE( " outerRect.iTl.iY = %d", outerRect.iTl.iY ); |
|
2998 _AKNTRACE( " outerRect.iBr.iX = %d", outerRect.iBr.iX ); |
|
2999 _AKNTRACE( " outerRect.iBr.iY = %d", outerRect.iBr.iY ); |
|
3000 |
|
3001 _AKNTRACE( " innerRect.iTl.iX = %d", innerRect.iTl.iX ); |
|
3002 _AKNTRACE( " innerRect.iTl.iY = %d", innerRect.iTl.iY ); |
|
3003 _AKNTRACE( " innerRect.iBr.iX = %d", innerRect.iBr.iX ); |
|
3004 _AKNTRACE( " innerRect.iBr.iY = %d", innerRect.iBr.iY ); |
|
3005 _AKNTRACE_FUNC_EXIT; |
|
3006 } |
|
3007 |
|
3008 // ----------------------------------------------------------------------------- |
|
3009 // CEikMenuPane::RepaintHighlight |
|
3010 // ----------------------------------------------------------------------------- |
|
3011 // |
|
3012 void CEikMenuPane::RepaintHighlight() const |
|
3013 { |
|
3014 if ( !iExtension->iSctHighlighted ) |
|
3015 { |
|
3016 DrawItem( SelectedItem(), EDrawHighlight ); |
|
3017 } |
|
3018 } |
|
3019 |
|
3020 |
|
3021 // ----------------------------------------------------------------------------- |
|
3022 // CEikMenuPane::MoveHighlightTo |
|
3023 // Moves the menu pane highlight to the new selected menu item aNewSelectedItem. |
|
3024 // ----------------------------------------------------------------------------- |
|
3025 // |
|
3026 EXPORT_C void CEikMenuPane::MoveHighlightTo(TInt aNewSelectedItem) |
|
3027 { |
|
3028 _AKNTRACE_FUNC_ENTER; |
|
3029 _AKNTRACE( "aNewSelectedItem = %d", aNewSelectedItem ); |
|
3030 _AKNTRACE( "iSelectedItem = %d", iSelectedItem ); |
|
3031 if ( aNewSelectedItem == iSelectedItem ) |
|
3032 { |
|
3033 return; |
|
3034 } |
|
3035 |
|
3036 iExtension->StopCascadeMenuTimer(); |
|
3037 TInt previousTopItem = iScroller->TopItemIndex(); |
|
3038 TInt previousSelectedItem = iSelectedItem; |
|
3039 _AKNTRACE( "previousTopItem = %d", previousTopItem ); |
|
3040 _AKNTRACE( "previousSelectedItem = %d", previousSelectedItem ); |
|
3041 |
|
3042 ActivateGc(); |
|
3043 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3044 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
3045 if ( transApi ) |
|
3046 { |
|
3047 iExtension->iGc->Activate( *DrawableWindow() ); |
|
3048 } |
|
3049 CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc(); |
|
3050 #else |
|
3051 CWindowGc& gc = SystemGc(); |
|
3052 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3053 PrepareGcForDrawingItems( gc ); |
|
3054 |
|
3055 // Scrollers top item index must be updated first because setting selected |
|
3056 // item results in animation redraw (which requires knowledge about the |
|
3057 // current top item). |
|
3058 if ( aNewSelectedItem >= 0 ) |
|
3059 { |
|
3060 ScrollToMakeItemVisible( aNewSelectedItem ); |
|
3061 } |
|
3062 else |
|
3063 { |
|
3064 ScrollToMakeItemVisible( 0 ); |
|
3065 } |
|
3066 |
|
3067 TInt topItem = iScroller->TopItemIndex(); |
|
3068 TInt bottomItem = topItem + NumberOfItemsThatFitInView(); |
|
3069 if( bottomItem > NumberOfItemsInPane() ) |
|
3070 { |
|
3071 bottomItem = NumberOfItemsInPane(); |
|
3072 } |
|
3073 _AKNTRACE( "topItem = %d", topItem ); |
|
3074 _AKNTRACE( "bottomItem = %d", bottomItem ); |
|
3075 // When the SCT row will be highlight, remove highlight from |
|
3076 // bottom's and top's item. |
|
3077 if (iExtension->iSctHighlighted) |
|
3078 { |
|
3079 DrawItem( gc, topItem, ERemoveHighlight ); |
|
3080 DrawItem( gc, (bottomItem-1), ERemoveHighlight ); |
|
3081 } |
|
3082 SetSelectedItem( aNewSelectedItem ); |
|
3083 |
|
3084 PrepareHighlightFrame(); |
|
3085 |
|
3086 if ( previousTopItem == topItem && aNewSelectedItem >= 0 ) |
|
3087 { |
|
3088 // then only previuosly and currently selected items should be redrawn |
|
3089 DrawItem( gc, previousSelectedItem, ERemoveHighlight ); |
|
3090 |
|
3091 if ( !iExtension->iSctHighlighted ) |
|
3092 { |
|
3093 DrawItem( gc, aNewSelectedItem, EDrawHighlight ); |
|
3094 } |
|
3095 } |
|
3096 else |
|
3097 { |
|
3098 TBool skipHighlight = EFalse; |
|
3099 if (iExtension && iExtension->iSct && aNewSelectedItem == 0 && |
|
3100 previousSelectedItem > 1) |
|
3101 { |
|
3102 skipHighlight = ETrue; |
|
3103 } |
|
3104 for( TInt i = topItem; i<bottomItem; i++ ) |
|
3105 { |
|
3106 if( i == aNewSelectedItem && !skipHighlight) |
|
3107 { |
|
3108 DrawItem( gc, i, EDrawHighlight ); |
|
3109 } |
|
3110 else |
|
3111 { |
|
3112 DrawItem( gc, i, ERemoveHighlight ); |
|
3113 } |
|
3114 } |
|
3115 } |
|
3116 |
|
3117 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3118 if ( transApi ) |
|
3119 { |
|
3120 iExtension->iGc->Deactivate(); |
|
3121 } |
|
3122 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3123 DeactivateGc(); |
|
3124 |
|
3125 UpdateScrollBarThumbs(); |
|
3126 |
|
3127 // Updating view position here prevents some flickering |
|
3128 iExtension->ViewPositionChanged( iExtension->iViewPosition ); |
|
3129 |
|
3130 _AKNTRACE_FUNC_EXIT; |
|
3131 } |
|
3132 |
|
3133 // ----------------------------------------------------------------------------- |
|
3134 // CEikMenuPane::PrepareGcForDrawingItems |
|
3135 // ----------------------------------------------------------------------------- |
|
3136 // |
|
3137 void CEikMenuPane::PrepareGcForDrawingItems(CGraphicsContext& aGc) const |
|
3138 { |
|
3139 |
|
3140 // BIDI |
|
3141 /* |
|
3142 * get the fonts from the LAF! |
|
3143 * Do we need to get them here? - nope - moved to DrawItem() |
|
3144 */ |
|
3145 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3146 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
3147 if ( transApi ) |
|
3148 { |
|
3149 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); |
|
3150 } |
|
3151 #endif |
|
3152 |
|
3153 aGc.SetPenColor(iEikonEnv->ControlColor( EColorMenuPaneText, *this) ); |
|
3154 #if defined(MENU_TEXTURED_BACKGROUND) |
|
3155 iEikonEnv->SetTexturedBrush( aGc ); |
|
3156 #else |
|
3157 aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
3158 aGc.SetBrushColor( iEikonEnv->ControlColor( EColorMenuPaneBackground,*this ) ); |
|
3159 #endif |
|
3160 |
|
3161 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3162 if ( transApi ) |
|
3163 { |
|
3164 transApi->StopDrawing(); |
|
3165 } |
|
3166 #endif |
|
3167 } |
|
3168 |
|
3169 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3170 /** |
|
3171 * Iterate through the visible items in a menu and calculate minimum |
|
3172 * item margins that dont need drawing. |
|
3173 */ |
|
3174 void CEikMenuPaneExtension::CalcItemSize( MAknListBoxTfxInternal* transApi ) const |
|
3175 { |
|
3176 if ( transApi && iControl->iItemArray && iControl->iItemArray->Count() ) |
|
3177 { |
|
3178 TRect marginRect(TRect::EUninitialized); |
|
3179 const TInt index = 0; |
|
3180 |
|
3181 // Specifies whether the text should be moved to give some space for icon. |
|
3182 TInt hasIcon = iControl->MenuHasIcon() ? 1 : 0; |
|
3183 |
|
3184 TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) ); |
|
3185 TAknWindowLineLayout singleMenuPane( |
|
3186 AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) ); |
|
3187 TAknTextLineLayout menuTextLayout( |
|
3188 AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0) ); |
|
3189 |
|
3190 TAknLayoutRect menuPaneRect; |
|
3191 TAknLayoutRect singleMenuPaneRect; |
|
3192 TAknLayoutText textRect; |
|
3193 |
|
3194 TBool hasCascade = EFalse; |
|
3195 TBool hasNonCascade = EFalse; |
|
3196 |
|
3197 // number of items in the whole menu |
|
3198 for(TInt i = 0; i < iControl->iItemArray->Count(); i++) |
|
3199 { |
|
3200 CEikMenuPaneItem* item = (*iControl->iItemArray)[i]; |
|
3201 |
|
3202 // true if a cascade symbol must be drawn (main menu only) |
|
3203 TBool cascade = item->iData.iCascadeId != 0; |
|
3204 |
|
3205 if ( cascade ) |
|
3206 { |
|
3207 if ( hasCascade ) |
|
3208 { |
|
3209 if ( hasNonCascade ) |
|
3210 { |
|
3211 break; |
|
3212 } |
|
3213 continue; |
|
3214 } |
|
3215 hasCascade = ETrue; |
|
3216 } |
|
3217 else |
|
3218 { |
|
3219 if ( hasNonCascade ) |
|
3220 { |
|
3221 if ( hasCascade ) |
|
3222 { |
|
3223 break; |
|
3224 } |
|
3225 continue; |
|
3226 } |
|
3227 hasNonCascade = ETrue; |
|
3228 } |
|
3229 |
|
3230 if ( !iControl->iOwner ) |
|
3231 { |
|
3232 TAknWindowLineLayout listScrollPaneLayout( |
|
3233 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
3234 AdjustPopupLayoutData( listScrollPaneLayout ); |
|
3235 TAknLayoutRect listScrollPaneRect; |
|
3236 listScrollPaneRect.LayoutRect( iControl->Rect(), listScrollPaneLayout ); |
|
3237 |
|
3238 menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); |
|
3239 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
3240 |
|
3241 singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine(); |
|
3242 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); |
|
3243 |
|
3244 menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine(); |
|
3245 } |
|
3246 else // Submenu |
|
3247 { |
|
3248 TBool hasDoubleSpanScrollBar = EFalse; |
|
3249 if ( iControl->iOwner && iControl->iSBFrame && |
|
3250 iControl->iSBFrame->VScrollBarVisibility() ) |
|
3251 { |
|
3252 hasDoubleSpanScrollBar = ETrue; |
|
3253 } |
|
3254 TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); |
|
3255 TAknLayoutRect listScrollPaneRect; |
|
3256 listScrollPaneRect.LayoutRect( iControl->Rect(), listScrollPaneLayout ); |
|
3257 |
|
3258 menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine(); |
|
3259 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
3260 |
|
3261 singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine(); |
|
3262 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); |
|
3263 |
|
3264 menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( hasIcon ).LayoutLine() ); |
|
3265 } |
|
3266 |
|
3267 textRect.LayoutText( singleMenuPaneRect.Rect(), menuTextLayout ); |
|
3268 if (marginRect == TRect::EUninitialized) |
|
3269 { |
|
3270 marginRect = textRect.TextRect(); |
|
3271 } |
|
3272 else |
|
3273 { |
|
3274 marginRect.BoundingRect(textRect.TextRect()); |
|
3275 } |
|
3276 |
|
3277 if ( cascade ) |
|
3278 { |
|
3279 TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine()); |
|
3280 TAknLayoutRect cascadeRect; |
|
3281 cascadeRect.LayoutRect( singleMenuPaneRect.Rect(), elementCascade ); |
|
3282 marginRect.BoundingRect(cascadeRect.Rect()); |
|
3283 } |
|
3284 else |
|
3285 { |
|
3286 TAknLayoutRect activeApplicationsIconRect; |
|
3287 activeApplicationsIconRect.LayoutRect( singleMenuPaneRect.Rect(), |
|
3288 AknLayoutScalable_Avkon::list_single_pane_g1_cp2(0).LayoutLine() ); |
|
3289 marginRect.BoundingRect(activeApplicationsIconRect.Rect()); |
|
3290 } |
|
3291 } |
|
3292 |
|
3293 if ( hasIcon ) |
|
3294 { |
|
3295 TAknLayoutRect iconLayoutRect; |
|
3296 iconLayoutRect.LayoutRect( singleMenuPaneRect.Rect(), |
|
3297 AknLayoutScalable_Avkon::list_single_popup_submenu_pane_g1().LayoutLine() ); |
|
3298 marginRect.BoundingRect(iconLayoutRect.Rect()); |
|
3299 } |
|
3300 |
|
3301 //send margins to tfx |
|
3302 TPoint tl ( marginRect.iTl - menuPaneRect.Rect().iTl ); |
|
3303 transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, tl ); |
|
3304 |
|
3305 TPoint br( singleMenuPaneRect.Rect().Size().AsPoint() - marginRect.iBr + menuPaneRect.Rect().iTl ); |
|
3306 transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, br ); |
|
3307 } |
|
3308 } |
|
3309 #endif |
|
3310 |
|
3311 |
|
3312 // --------------------------------------------------------------------------- |
|
3313 // CEikMenuPane::DrawItem |
|
3314 // --------------------------------------------------------------------------- |
|
3315 // |
|
3316 void CEikMenuPane::DrawItem( TInt aItem, THighlightType aHighlight ) const |
|
3317 { |
|
3318 ActivateGc(); |
|
3319 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3320 MAknListBoxTfxInternal* transApi = |
|
3321 CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
3322 |
|
3323 if ( transApi ) |
|
3324 { |
|
3325 iExtension->iGc->Activate( *DrawableWindow() ); |
|
3326 } |
|
3327 |
|
3328 CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc(); |
|
3329 #else |
|
3330 CWindowGc& gc = SystemGc(); |
|
3331 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3332 PrepareGcForDrawingItems( gc ); |
|
3333 DrawItem( gc, aItem, aHighlight ); |
|
3334 |
|
3335 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3336 if ( transApi ) |
|
3337 { |
|
3338 iExtension->iGc->Deactivate(); |
|
3339 } |
|
3340 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3341 DeactivateGc(); |
|
3342 } |
|
3343 |
|
3344 |
|
3345 // --------------------------------------------------------------------------- |
|
3346 // CEikMenuPane::DrawItem |
|
3347 // --------------------------------------------------------------------------- |
|
3348 // |
|
3349 void CEikMenuPane::DrawItem(CWindowGc& aGc,TInt aItem,THighlightType aHighlight) const |
|
3350 // BIDI - no hotkey text. No pre-adornments |
|
3351 { |
|
3352 if ( !iItemArray || iItemArray->Count() == 0 || aItem == ENothingSelected ) |
|
3353 { |
|
3354 return; |
|
3355 } |
|
3356 |
|
3357 TInt numItemsInArray = iItemArray->Count(); |
|
3358 |
|
3359 __ASSERT_DEBUG( aItem < numItemsInArray, Panic( EEikPanicNoSuchMenuItem ) ); |
|
3360 |
|
3361 if ( aItem >= numItemsInArray ) |
|
3362 { |
|
3363 return; |
|
3364 } |
|
3365 |
|
3366 // seem to have window owning control in correct place |
|
3367 TRect windowRect = Rect(); |
|
3368 |
|
3369 if ( !iOwner ) |
|
3370 { |
|
3371 windowRect.iBr.iY -= ( iExtension->iCba->Rect().Height() ); |
|
3372 } |
|
3373 |
|
3374 CEikMenuPaneItem* item = (*iItemArray)[aItem]; |
|
3375 // Max visible number of items in menu / submenu |
|
3376 TInt maxNumberOfItems = NumberOfItemsThatFitInView(); |
|
3377 |
|
3378 TInt topIndex = iScroller->TopItemIndex(); |
|
3379 // true if a cascade symbol must be drawn (main menu only) |
|
3380 TBool cascade = ( item->iData.iCascadeId != 0 ); |
|
3381 |
|
3382 // Specifies whether the text should be moved to give some space for icon. |
|
3383 TBool hasIcon = MenuHasIcon(); |
|
3384 |
|
3385 if ( iExtension->iSct ) |
|
3386 { |
|
3387 ++maxNumberOfItems; |
|
3388 ++numItemsInArray; |
|
3389 } |
|
3390 |
|
3391 // number of items in the whole menu |
|
3392 TInt numItems = Min( Max( 1, numItemsInArray ), maxNumberOfItems ); |
|
3393 TInt index = aItem - topIndex; |
|
3394 |
|
3395 if ( iExtension->iSct ) |
|
3396 { |
|
3397 // Sct row exists -> the rest of the menu items are pushed down |
|
3398 // in visual representation. |
|
3399 ++index; |
|
3400 } |
|
3401 TInt itemLeftInBottom = maxNumberOfItems -(numItemsInArray - topIndex); |
|
3402 if ( (itemLeftInBottom > 0) && (topIndex > 0) ) |
|
3403 { |
|
3404 index += itemLeftInBottom; |
|
3405 } |
|
3406 |
|
3407 TBool drawPartialItem(EFalse); |
|
3408 if ( index == maxNumberOfItems ) |
|
3409 { |
|
3410 // We have partial items to draw because of panning so there |
|
3411 // is one more item to draw than normally. |
|
3412 drawPartialItem = ETrue; |
|
3413 // There is no layout data for the extra item, so we used the one |
|
3414 // above it. |
|
3415 --index; |
|
3416 } |
|
3417 |
|
3418 // If in Menu Sct, skip the first row of the recent used characters |
|
3419 if ( index < 0 || index >= maxNumberOfItems || (iExtension->iSct && index==0)) |
|
3420 { |
|
3421 return; // only interested in drawing visible items |
|
3422 } |
|
3423 |
|
3424 // Collect all of the information from the Layout DLL. Initialise these |
|
3425 // variables with DUMMY data. Then replace it with menu/submenu data. |
|
3426 TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) ); |
|
3427 TAknWindowLineLayout singleMenuPane( |
|
3428 AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) ); |
|
3429 TAknTextLineLayout menuTextLayout( |
|
3430 AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0) ); |
|
3431 TAknLayoutRect menuPaneRect; |
|
3432 TAknLayoutRect singleMenuPaneRect; |
|
3433 |
|
3434 if ( !iOwner ) |
|
3435 { |
|
3436 TAknWindowLineLayout listScrollPaneLayout( |
|
3437 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
3438 if ( iExtension ) |
|
3439 { |
|
3440 iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); |
|
3441 } |
|
3442 TAknLayoutRect listScrollPaneRect; |
|
3443 listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); |
|
3444 |
|
3445 menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); |
|
3446 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
3447 |
|
3448 singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine(); |
|
3449 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); |
|
3450 |
|
3451 menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine(); |
|
3452 } |
|
3453 else // Submenu |
|
3454 { |
|
3455 TBool hasDoubleSpanScrollBar = EFalse; |
|
3456 if ( iSBFrame && iSBFrame->VScrollBarVisibility() ) |
|
3457 { |
|
3458 hasDoubleSpanScrollBar = ETrue; |
|
3459 } |
|
3460 |
|
3461 TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); |
|
3462 TAknLayoutRect listScrollPaneRect; |
|
3463 listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); |
|
3464 |
|
3465 menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine(); |
|
3466 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
3467 |
|
3468 singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine(); |
|
3469 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); |
|
3470 |
|
3471 menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() ); |
|
3472 |
|
3473 if ( hasIcon ) |
|
3474 { |
|
3475 menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() ); |
|
3476 } |
|
3477 } |
|
3478 |
|
3479 TRect itemRect( singleMenuPaneRect.Rect() ); |
|
3480 |
|
3481 // Move the rect with our panning offset. |
|
3482 itemRect.iTl.iY += iExtension->Offset(); |
|
3483 itemRect.iBr.iY += iExtension->Offset(); |
|
3484 if( drawPartialItem ) |
|
3485 { |
|
3486 // For the extra item, also move it one full item height |
|
3487 itemRect.iTl.iY += iItemHeight; |
|
3488 itemRect.iBr.iY += iItemHeight; |
|
3489 } |
|
3490 |
|
3491 TBool drawingInitiated = ETrue; |
|
3492 |
|
3493 RWindow& window = Window(); |
|
3494 |
|
3495 if ( &window && window.GetDrawRect() == TRect::EUninitialized ) |
|
3496 { |
|
3497 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3498 MAknListBoxTfxInternal* transApi = |
|
3499 CAknListLoader::TfxApiInternal( &aGc ); |
|
3500 drawingInitiated = transApi && !transApi->EffectsDisabled(); |
|
3501 #else |
|
3502 drawingInitiated = EFalse; |
|
3503 #endif |
|
3504 } |
|
3505 |
|
3506 if ( !drawingInitiated ) |
|
3507 { |
|
3508 window.Invalidate( itemRect ); |
|
3509 window.BeginRedraw( itemRect ); |
|
3510 } |
|
3511 |
|
3512 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
3513 MAknsControlContext* cc = NULL; |
|
3514 if( iExtension ) |
|
3515 { |
|
3516 cc = iExtension->iBgContext; |
|
3517 } |
|
3518 TBool background( ETrue ); |
|
3519 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3520 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &aGc ); |
|
3521 if ( transApi && !transApi->EffectsDisabled() ) |
|
3522 { |
|
3523 iExtension->iGc->Activate( *DrawableWindow() ); |
|
3524 } |
|
3525 #endif |
|
3526 |
|
3527 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3528 if ( !transApi || transApi->EffectsDisabled() ) |
|
3529 { |
|
3530 #endif |
|
3531 aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
3532 aGc.SetBrushColor( singleMenuPaneRect.Color() ); |
|
3533 |
|
3534 if(!iExtension->iFullRedraw) |
|
3535 { |
|
3536 background = AknsDrawUtils::Background( |
|
3537 skin, cc, this, aGc, itemRect, |
|
3538 KAknsDrawParamNoClearUnderImage ); |
|
3539 } |
|
3540 |
|
3541 if( !background ) |
|
3542 { |
|
3543 aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
3544 aGc.SetPenStyle( CGraphicsContext::ENullPen ); |
|
3545 aGc.SetPenColor( singleMenuPaneRect.Color() ); |
|
3546 aGc.SetBrushColor( singleMenuPaneRect.Color() ); |
|
3547 aGc.DrawRect( itemRect ); |
|
3548 } |
|
3549 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3550 } |
|
3551 #endif |
|
3552 |
|
3553 if ( !iExtension->HighlightEnabled() ) |
|
3554 { |
|
3555 aHighlight = ENoHighlight; |
|
3556 } |
|
3557 |
|
3558 switch ( aHighlight ) |
|
3559 { |
|
3560 case EDrawHighlight : |
|
3561 { |
|
3562 if ( !iExtension->iSctHighlighted ) |
|
3563 { |
|
3564 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3565 if ( transApi ) |
|
3566 { |
|
3567 // This will remove the old bitmap |
|
3568 transApi->Invalidate( MAknListBoxTfxInternal::EListHighlight ); |
|
3569 |
|
3570 transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, |
|
3571 itemRect ); |
|
3572 transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight ); |
|
3573 } |
|
3574 #endif |
|
3575 |
|
3576 // Partial items, so prevent drawing over the edge of menu pane |
|
3577 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3578 if ( !transApi || ( transApi && transApi->EffectsDisabled() ) ) |
|
3579 { |
|
3580 aGc.SetClippingRect(menuPaneRect.Rect()); |
|
3581 } |
|
3582 #else |
|
3583 aGc.SetClippingRect(menuPaneRect.Rect()); |
|
3584 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3585 |
|
3586 TBool drawOk = EFalse; |
|
3587 if( iExtension->iAnimation ) // Draw animated highlight |
|
3588 { |
|
3589 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3590 if ( transApi && transApi->VerifyKml() == KErrNone ) |
|
3591 { |
|
3592 Extension()->UseNoAnimation(); |
|
3593 } |
|
3594 else |
|
3595 { |
|
3596 #endif |
|
3597 TAknLayoutRect highlightTopLeft; |
|
3598 TAknLayoutRect highlightBottomRight; |
|
3599 |
|
3600 highlightTopLeft.LayoutRect( itemRect, |
|
3601 SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() ); |
|
3602 highlightBottomRight.LayoutRect( itemRect, |
|
3603 SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() ); |
|
3604 |
|
3605 TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr ); |
|
3606 |
|
3607 drawOk = iExtension->iAnimation->Render( aGc, outerRect ); |
|
3608 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3609 } |
|
3610 #endif |
|
3611 } |
|
3612 |
|
3613 if( !drawOk ) |
|
3614 { |
|
3615 // Animated highlight was not available, use normal skinned |
|
3616 // rendering. |
|
3617 |
|
3618 // Because of transparency, background must be drawn here as well |
|
3619 // (as frame may be see-through) |
|
3620 aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
3621 aGc.SetBrushColor( singleMenuPaneRect.Color() ); |
|
3622 |
|
3623 AknsDrawUtils::Background( |
|
3624 skin, cc, this, aGc, itemRect, |
|
3625 KAknsDrawParamNoClearUnderImage ); |
|
3626 |
|
3627 TAknLayoutRect highlightTopLeft; |
|
3628 TAknLayoutRect highlightBottomRight; |
|
3629 |
|
3630 highlightTopLeft.LayoutRect(itemRect, |
|
3631 SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() ); |
|
3632 highlightBottomRight.LayoutRect(itemRect, |
|
3633 SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() ); |
|
3634 TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr ); |
|
3635 TRect innerRect( highlightTopLeft.Rect().iBr, highlightBottomRight.Rect().iTl ); |
|
3636 |
|
3637 drawOk = AknsDrawUtils::DrawFrame( skin, |
|
3638 aGc, |
|
3639 outerRect, |
|
3640 innerRect, |
|
3641 KAknsIIDQsnFrList, |
|
3642 KAknsIIDDefault ); |
|
3643 |
|
3644 } |
|
3645 |
|
3646 // Both animated highlight and normal highlight drawing have |
|
3647 // failed. |
|
3648 if( !drawOk ) |
|
3649 { |
|
3650 TAknLayoutRect shadowRect; |
|
3651 TAknLayoutRect highlightRect; |
|
3652 shadowRect.LayoutRect( itemRect, |
|
3653 AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_1( itemRect ) ); |
|
3654 highlightRect.LayoutRect( itemRect, |
|
3655 AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_2( itemRect ) ); |
|
3656 aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
3657 shadowRect.DrawRect( aGc ); |
|
3658 highlightRect.DrawRect( aGc ); |
|
3659 } |
|
3660 |
|
3661 aGc.CancelClippingRect(); |
|
3662 |
|
3663 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3664 if ( transApi ) |
|
3665 { |
|
3666 transApi->StopDrawing(); |
|
3667 transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight ); |
|
3668 } |
|
3669 #endif |
|
3670 } |
|
3671 break; |
|
3672 } |
|
3673 case ERemoveHighlight: |
|
3674 case ENoHighlight: |
|
3675 default: |
|
3676 break; |
|
3677 } |
|
3678 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3679 if ( transApi ) |
|
3680 { |
|
3681 transApi->BeginRedraw( MAknListBoxTfxInternal::EListItem, itemRect, aItem ); |
|
3682 transApi->StartDrawing( MAknListBoxTfxInternal::EListItem ); |
|
3683 } |
|
3684 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3685 |
|
3686 // Partial items, so prevent drawing over the edge of menu pane |
|
3687 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3688 if ( !transApi || ( transApi && transApi->EffectsDisabled() ) ) |
|
3689 { |
|
3690 aGc.SetClippingRect(menuPaneRect.Rect()); |
|
3691 } |
|
3692 #else |
|
3693 aGc.SetClippingRect(menuPaneRect.Rect()); |
|
3694 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3695 |
|
3696 // Cascade |
|
3697 if ( cascade ) |
|
3698 { |
|
3699 TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine()); |
|
3700 TAknLayoutRect cascadeRect; |
|
3701 cascadeRect.LayoutRect( itemRect, elementCascade ); |
|
3702 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
3703 CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>( |
|
3704 skin->GetCachedItemData( KAknsIIDQgnIndiSubmenu, EAknsITMaskedBitmap ) ); |
|
3705 if( itemData ) |
|
3706 { |
|
3707 aGc.BitBltMasked( cascadeRect.Rect().iTl, itemData->Bitmap(), |
|
3708 cascadeRect.Rect().Size(), itemData->Mask(), ETrue ); |
|
3709 } |
|
3710 else |
|
3711 { |
|
3712 aGc.BitBltMasked( cascadeRect.Rect().iTl, iExtension->iCascadeBitmap, |
|
3713 cascadeRect.Rect().Size(), iExtension->iCascadeBitmapMask, ETrue ); |
|
3714 } |
|
3715 } |
|
3716 else |
|
3717 { |
|
3718 TAknLayoutRect activeApplicationsIconRect; |
|
3719 activeApplicationsIconRect.LayoutRect( itemRect, |
|
3720 AknLayoutScalable_Avkon::list_single_pane_g1_cp2(0).LayoutLine() ); |
|
3721 item->DrawItemIcon( aGc, activeApplicationsIconRect.Rect(), EFalse, 0); |
|
3722 } |
|
3723 |
|
3724 if ( hasIcon ) |
|
3725 { |
|
3726 TAknLayoutRect iconLayoutRect; |
|
3727 iconLayoutRect.LayoutRect( itemRect, |
|
3728 AknLayoutScalable_Avkon::list_single_popup_submenu_pane_g1().LayoutLine() ); |
|
3729 |
|
3730 TRect iconRect = iconLayoutRect.Rect(); |
|
3731 |
|
3732 // radio button group |
|
3733 if ( iExtension->iHasRadioGroup ) |
|
3734 { |
|
3735 if( IsItemMemberOfRadioButtonGroup(aItem) ) |
|
3736 { |
|
3737 if ( iExtension->iSelectedRadioButtonItem == KNoSelectedRadioButtonItem && |
|
3738 item->iData.iFlags&EEikMenuItemRadioStart ) |
|
3739 { |
|
3740 // just to be sure that some radio button is set on |
|
3741 iExtension->iSelectedRadioButtonItem = aItem; |
|
3742 } |
|
3743 |
|
3744 if ( aItem == iExtension->iSelectedRadioButtonItem ) |
|
3745 { |
|
3746 // draw radio button |
|
3747 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
3748 CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>( |
|
3749 skin->GetCachedItemData( KAknsIIDQgnIndiRadiobuttOn, EAknsITMaskedBitmap ) ); |
|
3750 CFbsBitmap* radioButtonBmp = iExtension->iRadioButtonBitmap; |
|
3751 CFbsBitmap* radioButtonMask = iExtension->iRadioButtonBitmapMask; |
|
3752 if( itemData ) |
|
3753 { |
|
3754 radioButtonBmp = itemData->Bitmap(); |
|
3755 radioButtonMask = itemData->Mask(); |
|
3756 } |
|
3757 if( radioButtonBmp && radioButtonMask ) |
|
3758 { |
|
3759 AknIconUtils::SetSize( radioButtonBmp, iconRect.Size() ); |
|
3760 aGc.BitBltMasked( iconRect.iTl, radioButtonBmp, |
|
3761 iconRect.Size(), radioButtonMask, ETrue ); |
|
3762 } |
|
3763 } |
|
3764 } |
|
3765 } |
|
3766 else if ( item->iData.iFlags&EEikMenuItemSymbolOn ) |
|
3767 // draw check mark |
|
3768 { |
|
3769 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
3770 CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>( |
|
3771 skin->GetCachedItemData( KAknsIIDQgnIndiMarkedAdd, EAknsITMaskedBitmap ) ); |
|
3772 CFbsBitmap* checkMarkBmp = iExtension->iCheckMarkBitmap; |
|
3773 CFbsBitmap* checkMarkMask = iExtension->iCheckMarkBitmapMask; |
|
3774 if( itemData ) |
|
3775 { |
|
3776 checkMarkBmp = itemData->Bitmap(); |
|
3777 checkMarkMask = itemData->Mask(); |
|
3778 } |
|
3779 if( checkMarkBmp && checkMarkMask ) |
|
3780 { |
|
3781 AknIconUtils::SetSize( checkMarkBmp, iconRect.Size() ); |
|
3782 aGc.BitBltMasked( iconRect.iTl, checkMarkBmp, |
|
3783 iconRect.Size(), checkMarkMask, ETrue ); |
|
3784 } |
|
3785 } |
|
3786 } |
|
3787 |
|
3788 // Text |
|
3789 TAknLayoutText textRect( iExtension->GetMenuItemTextLayout( itemRect, cascade ) ); |
|
3790 TRgb textColor = textRect.Color(); |
|
3791 if ( aHighlight == EDrawHighlight ) // highlighted text |
|
3792 { |
|
3793 AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG10 ); |
|
3794 } |
|
3795 else if ( !iOwner ) // menu |
|
3796 { |
|
3797 AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19 ); |
|
3798 } |
|
3799 else // submenu |
|
3800 { |
|
3801 AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG20 ); |
|
3802 } |
|
3803 |
|
3804 //when OOM, the background is White, if the font's color is white, hardcode it to black |
|
3805 if( !background && aHighlight != EDrawHighlight ) |
|
3806 { |
|
3807 const TInt KRate = 95; // 95% similar rate |
|
3808 const TInt KFullColor = 255; |
|
3809 TInt redcolor = textColor.Red(); |
|
3810 TInt bluecolor = textColor.Blue(); |
|
3811 TInt greencolor = textColor.Green(); |
|
3812 // test if the color is too similar to white color |
|
3813 if ( redcolor > KFullColor * KRate / 100 || |
|
3814 bluecolor > KFullColor * KRate / 100 || |
|
3815 greencolor > KFullColor * KRate / 100 ) |
|
3816 { |
|
3817 textColor = KRgbBlack; |
|
3818 } |
|
3819 } |
|
3820 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
3821 aGc.SetPenColor( textColor ); |
|
3822 aGc.UseFont( textRect.Font() ); |
|
3823 |
|
3824 const CFont* font = textRect.Font(); |
|
3825 |
|
3826 //TBuf<CEikMenuPaneItem::SData::ENominalTextLength + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text |
|
3827 TBuf<255 + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text |
|
3828 |
|
3829 TInt clipWidth = textRect.TextRect().Width(); |
|
3830 |
|
3831 AknBidiTextUtils::ConvertToVisualAndClip( |
|
3832 item->ScaleableText(), |
|
3833 visualText, |
|
3834 *font, |
|
3835 clipWidth, |
|
3836 clipWidth ); |
|
3837 |
|
3838 textRect.DrawText( aGc, visualText, EFalse, textColor ); |
|
3839 |
|
3840 // calculate demarcation rectangle for cascaded menu item |
|
3841 if (iCascadeMenuPane) |
|
3842 { |
|
3843 TPoint position( PositionRelativeToScreen() ); |
|
3844 TRect cascRect( textRect.TextRect() ); |
|
3845 cascRect.Move( position ); |
|
3846 iExtension->iCascadeDRect.SetRect( cascRect.iTl, cascRect.iBr ); |
|
3847 } |
|
3848 |
|
3849 if(iExtension->iIsPenEnable) |
|
3850 { |
|
3851 TAknLayoutRect highlightRect; |
|
3852 highlightRect.LayoutRect( itemRect, |
|
3853 AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_2( itemRect ) ); |
|
3854 |
|
3855 // store the calculated y-position to the menu item, |
|
3856 // so that it can be used in HandlePointerEventL() |
|
3857 item->iPos = highlightRect.Rect().iTl.iY; |
|
3858 aGc.DiscardFont(); |
|
3859 } |
|
3860 |
|
3861 if ( !drawingInitiated ) |
|
3862 { |
|
3863 Window().EndRedraw(); |
|
3864 } |
|
3865 |
|
3866 aGc.CancelClippingRect(); |
|
3867 |
|
3868 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3869 if ( transApi && !transApi->EffectsDisabled() ) |
|
3870 { |
|
3871 transApi->StopDrawing(); |
|
3872 transApi->EndRedraw( MAknListBoxTfxInternal::EListItem, aItem ); |
|
3873 iExtension->iGc->Deactivate(); |
|
3874 } |
|
3875 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3876 } |
|
3877 |
|
3878 |
|
3879 // ----------------------------------------------------------------------------- |
|
3880 // CEikMenuPane::Draw |
|
3881 // ----------------------------------------------------------------------------- |
|
3882 // |
|
3883 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3884 EXPORT_C void CEikMenuPane::Draw( const TRect& aRect ) const |
|
3885 { |
|
3886 CWindowGc& gc = ( iExtension && iExtension->iGc ) ? |
|
3887 *iExtension->iGc : SystemGc(); |
|
3888 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &gc ); |
|
3889 |
|
3890 if ( transApi ) |
|
3891 { |
|
3892 iExtension->iGc->Activate( *DrawableWindow() ); |
|
3893 |
|
3894 if ( !transApi->EffectsDisabled() ) |
|
3895 { |
|
3896 if ( iExtension->iScrollBarRect.iTl.iX <= aRect.iTl.iX && |
|
3897 iExtension->iScrollBarRect.iBr.iX >= aRect.iBr.iX ) |
|
3898 { |
|
3899 transApi->BeginRedraw( MAknListBoxTfxInternal::EListUpdateRect, aRect ); |
|
3900 iExtension->iGc->Deactivate(); |
|
3901 return; |
|
3902 } |
|
3903 |
|
3904 iExtension->CalcItemSize( transApi ); |
|
3905 } |
|
3906 } |
|
3907 #else |
|
3908 EXPORT_C void CEikMenuPane::Draw(const TRect& /*aRect*/) const |
|
3909 { |
|
3910 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3911 |
|
3912 TRect windowRect( Rect() ); |
|
3913 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
3914 MAknsControlContext* cc = NULL; |
|
3915 |
|
3916 if( iExtension ) |
|
3917 { |
|
3918 cc = iExtension->iBgContext; |
|
3919 } |
|
3920 |
|
3921 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3922 if ( transApi ) |
|
3923 { |
|
3924 transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeMenuPane ); |
|
3925 transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, windowRect ); |
|
3926 } |
|
3927 #else |
|
3928 CWindowGc& gc = SystemGc(); |
|
3929 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3930 PrepareGcForDrawingItems( gc ); |
|
3931 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3932 if ( transApi ) |
|
3933 { |
|
3934 transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); |
|
3935 } |
|
3936 #endif |
|
3937 |
|
3938 if ( !IsCascadeMenuPane() ) |
|
3939 { |
|
3940 CFbsBitmap* cbaExtension = AknsUtils::GetCachedBitmap( skin, KAknsIIDQsnBgSlicePopup ); |
|
3941 if ( cbaExtension ) |
|
3942 { |
|
3943 TAknLayoutRect sliceRect; |
|
3944 sliceRect.LayoutRect( windowRect, SkinLayout::Popup_windows_skin_placing__background_slice__Line_2() ); |
|
3945 AknIconUtils::SetSize( cbaExtension, sliceRect.Rect().Size() ); |
|
3946 gc.BitBlt( TPoint( windowRect.iTl.iX, windowRect.iBr.iY-cbaExtension->SizeInPixels().iHeight ), cbaExtension ); |
|
3947 windowRect.iBr.iY -=2; // two used as margin when rect layouts were done |
|
3948 } |
|
3949 } |
|
3950 |
|
3951 TInt count=0; |
|
3952 if( iItemArray ) |
|
3953 { |
|
3954 count=iItemArray->Count(); |
|
3955 } |
|
3956 |
|
3957 // Give the topmost menu item's rect to SCT if needed. |
|
3958 if ( iExtension->iSct ) |
|
3959 { |
|
3960 TAknLayoutRect listScrollPaneRect; |
|
3961 TAknLayoutRect menuPaneRect; |
|
3962 TAknLayoutRect singleMenuPaneRect; |
|
3963 |
|
3964 TAknWindowLineLayout listScrollPaneLayout( |
|
3965 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
3966 if ( iExtension ) |
|
3967 { |
|
3968 iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); |
|
3969 } |
|
3970 listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); |
|
3971 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), |
|
3972 AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine() ); |
|
3973 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), |
|
3974 AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine() ); |
|
3975 // Give the rect of the first menu item to SCT. |
|
3976 iExtension->iSct->SetMenuSctRect( singleMenuPaneRect.Rect() ); |
|
3977 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3978 if( transApi ) |
|
3979 { |
|
3980 iExtension->iSctRect = singleMenuPaneRect.Rect(); |
|
3981 TAknLayoutRect cellLayRect; |
|
3982 cellLayRect.LayoutRect( iExtension->iSctRect, |
|
3983 AknLayoutScalable_Avkon::cell_graphic_popup_pane( 0, 0, 0 ) ); |
|
3984 iExtension->iSctRect.iTl.iX -= 1; |
|
3985 iExtension->iSctRect.iTl.iY -= 1; |
|
3986 iExtension->iSctRect.iBr.iX += 3; |
|
3987 transApi->ResetNonDrawingRects(); |
|
3988 transApi->AddNonDrawingRect( iExtension->iScrollBarRect ); |
|
3989 transApi->AddNonDrawingRect( iExtension->iSctRect ); |
|
3990 } |
|
3991 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
3992 } |
|
3993 |
|
3994 if ( iExtension->iSct ) |
|
3995 { |
|
3996 TRegionFix<4> region; |
|
3997 region.AddRect( Rect() ); |
|
3998 region.SubRect( iExtension->iSct->Rect() ); |
|
3999 gc.SetClippingRegion( region ); |
|
4000 } |
|
4001 |
|
4002 TRect backgroundRect( iOwner ? windowRect : iExtension->GetBackgroundRect( windowRect ) ); |
|
4003 |
|
4004 // The added flag removes the white bg for transparency |
|
4005 TBool frameDrawn = AknsDrawUtils::Background( |
|
4006 skin, cc, this, gc, backgroundRect, KAknsDrawParamNoClearUnderImage ); |
|
4007 |
|
4008 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4009 if ( transApi ) |
|
4010 { |
|
4011 transApi->StopDrawing(); |
|
4012 } |
|
4013 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4014 |
|
4015 iExtension->iFullRedraw = ETrue; |
|
4016 |
|
4017 for ( TInt ii=0;ii<count;++ii ) |
|
4018 { |
|
4019 if(!iExtension->iSctHighlighted && ii == iSelectedItem ) |
|
4020 DrawItem( gc, ii, EDrawHighlight); |
|
4021 else |
|
4022 DrawItem( gc, ii, ENoHighlight); |
|
4023 } |
|
4024 |
|
4025 iExtension->iFullRedraw = EFalse; |
|
4026 |
|
4027 if ( iExtension->iSct ) |
|
4028 { |
|
4029 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4030 if ( transApi ) |
|
4031 { |
|
4032 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); |
|
4033 } |
|
4034 #endif |
|
4035 gc.CancelClippingRegion(); |
|
4036 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4037 if ( transApi ) |
|
4038 { |
|
4039 transApi->StopDrawing(); |
|
4040 } |
|
4041 #endif |
|
4042 } |
|
4043 |
|
4044 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4045 if ( transApi ) |
|
4046 { |
|
4047 transApi->EndViewRedraw( aRect ); |
|
4048 iExtension->iGc->Deactivate(); |
|
4049 } |
|
4050 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4051 } |
|
4052 |
|
4053 |
|
4054 // ----------------------------------------------------------------------------- |
|
4055 // CEikMenuPane::ReportSelectionMadeL |
|
4056 // ----------------------------------------------------------------------------- |
|
4057 // |
|
4058 void CEikMenuPane::ReportSelectionMadeL( TBool aAbortTransition ) |
|
4059 { |
|
4060 _AKNTRACE_FUNC_ENTER; |
|
4061 if( aAbortTransition ) |
|
4062 { |
|
4063 GfxTransEffect::Abort(); |
|
4064 } |
|
4065 if ( !iItemArray || iItemArray->Count() == 0 ) |
|
4066 { |
|
4067 return; |
|
4068 } |
|
4069 |
|
4070 if ( iCascadeMenuPane ) |
|
4071 { |
|
4072 SetFocus( EFalse, EDrawNow ); |
|
4073 iCascadeMenuPane->SetFocus( ETrue, EDrawNow ); |
|
4074 return; |
|
4075 } |
|
4076 |
|
4077 // means the cascade created on the down event is getting the up event |
|
4078 if ( iSelectedItem == ENothingSelected && !iExtension->iSctHighlighted) |
|
4079 { |
|
4080 return; |
|
4081 } |
|
4082 |
|
4083 CEikMenuPaneItem* item = NULL; |
|
4084 |
|
4085 // the sct highlight does not have index so do not try to get item with the index |
|
4086 if(iSelectedItem != ENothingSelected) |
|
4087 item = (*iItemArray)[iSelectedItem]; |
|
4088 |
|
4089 if ( item && item->iData.iFlags&EEikMenuItemDimmed ) |
|
4090 { |
|
4091 iMenuObserver->HandleAttemptDimmedSelectionL( item->iData.iCommandId ); |
|
4092 } |
|
4093 else |
|
4094 { |
|
4095 TInt commandId = 0; |
|
4096 if ( iExtension->iSctHighlighted ) |
|
4097 { |
|
4098 commandId = EAknCmdEditMenuSctSelected; |
|
4099 } |
|
4100 else if (item && !item->iData.iCascadeId) |
|
4101 { |
|
4102 commandId = item->iData.iCommandId; |
|
4103 } |
|
4104 |
|
4105 if ( commandId == EAknCmdTaskSwapper ) |
|
4106 { |
|
4107 if ( !iExtension->iTaskSwapIdle->IsActive() ) |
|
4108 { |
|
4109 iExtension->iTaskSwapIdle->Start( TCallBack( TaskSwapCallBack ) ); |
|
4110 } |
|
4111 } |
|
4112 |
|
4113 if ( !commandId ) return; // Nothing to process |
|
4114 |
|
4115 if ( iEditMenuObserver ) |
|
4116 iEditMenuObserver->ProcessCommandL( commandId ); |
|
4117 |
|
4118 // have to save pointer now because in case if we are in a submenu |
|
4119 // 'this' might be destroyed by calling iMenuObserver->ProcessCommandL( |
|
4120 // commandId ), so need to avoid crash |
|
4121 CEikMenuPane* menu = iOwner ? iOwner : this; |
|
4122 MCoeControlObserver* observer = menu->Observer(); |
|
4123 |
|
4124 |
|
4125 if ( commandId != EAknCmdTaskSwapper ) |
|
4126 { |
|
4127 _AKNTRACE( "commandId = %d", commandId ); |
|
4128 iMenuObserver->ProcessCommandL( commandId ); |
|
4129 } |
|
4130 else |
|
4131 { |
|
4132 ReportCanceled(); |
|
4133 return; |
|
4134 } |
|
4135 |
|
4136 // very important for the context sensitive menu because it will |
|
4137 // be closed only after this call. |
|
4138 if ( this && observer ) |
|
4139 { |
|
4140 observer->HandleControlEventL( menu, |
|
4141 MCoeControlObserver::EEventRequestExit ); |
|
4142 } |
|
4143 |
|
4144 MEikMenuObserver* fepMenuObserver = CAknEnv::Static()->FepMenuObserver(); |
|
4145 if ( fepMenuObserver ) |
|
4146 { |
|
4147 fepMenuObserver->ProcessCommandL( commandId ); |
|
4148 } |
|
4149 } |
|
4150 _AKNTRACE_FUNC_EXIT; |
|
4151 } |
|
4152 |
|
4153 |
|
4154 // ----------------------------------------------------------------------------- |
|
4155 // CEikMenuPane::FocusChanged |
|
4156 // ----------------------------------------------------------------------------- |
|
4157 // |
|
4158 EXPORT_C void CEikMenuPane::FocusChanged( TDrawNow aDrawNow ) |
|
4159 { |
|
4160 _AKNTRACE_FUNC_ENTER; |
|
4161 _AKNTRACE( "aDrawNow = %d", aDrawNow ); |
|
4162 if( iExtension ) |
|
4163 { |
|
4164 if ( IsFocused() ) |
|
4165 { |
|
4166 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4167 // Focus must be handled here, otherwise it will come to late |
|
4168 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
4169 |
|
4170 if ( transApi ) |
|
4171 { |
|
4172 transApi->HandleFocusChange( ETrue ); |
|
4173 } |
|
4174 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4175 iExtension->FocusGained(); |
|
4176 } |
|
4177 else // Not focused |
|
4178 { |
|
4179 iExtension->FocusLost(); |
|
4180 } |
|
4181 } |
|
4182 |
|
4183 if ( !iItemArray || iItemArray->Count() == 0 ) |
|
4184 { |
|
4185 return; |
|
4186 } |
|
4187 |
|
4188 if ( aDrawNow && iExtension->HighlightEnabled() ) |
|
4189 { |
|
4190 // if focused or if current item is a cascade draw highlight (only draw if item is selected) |
|
4191 if ( iSelectedItem != ENothingSelected ) |
|
4192 { |
|
4193 const CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem]; |
|
4194 THighlightType highlight = ERemoveHighlight; |
|
4195 |
|
4196 if ( !iExtension->iSctHighlighted && |
|
4197 ( item->iData.iCascadeId || IsFocused() ) ) |
|
4198 { |
|
4199 PrepareHighlightFrame(); |
|
4200 highlight = EDrawHighlight; |
|
4201 } |
|
4202 |
|
4203 DrawItem( iSelectedItem, highlight); |
|
4204 } |
|
4205 } |
|
4206 _AKNTRACE_FUNC_EXIT; |
|
4207 } |
|
4208 |
|
4209 // ----------------------------------------------------------------------------- |
|
4210 // CEikMenuPane::IsHotKeyL |
|
4211 // ----------------------------------------------------------------------------- |
|
4212 // |
|
4213 TBool CEikMenuPane::IsHotKeyL( const TInt modifiers, const TInt code ) |
|
4214 { |
|
4215 if ( iHotKeyTable ) |
|
4216 { |
|
4217 const TInt command = iHotKeyTable->CommandIdFromHotKey( code,modifiers ); |
|
4218 if ( command ) |
|
4219 { |
|
4220 if ( iMenuObserver->CheckHotKeyNotDimmedL( command) ) |
|
4221 { |
|
4222 // have to save pointer now because in case if we are in a submenu |
|
4223 // 'this' might be destroyed by calling iMenuObserver->ProcessCommandL( |
|
4224 // commandId ), so need to avoid crash |
|
4225 CEikMenuPane* menu = iOwner ? iOwner : this; |
|
4226 MCoeControlObserver* observer = menu->Observer(); |
|
4227 |
|
4228 iMenuObserver->ProcessCommandL( command ); |
|
4229 |
|
4230 // very important for the context sensitive menu because it will |
|
4231 // be closed only after this call. |
|
4232 if ( this && observer ) |
|
4233 { |
|
4234 observer->HandleControlEventL( menu, |
|
4235 MCoeControlObserver::EEventRequestExit ); |
|
4236 } |
|
4237 } |
|
4238 else |
|
4239 { |
|
4240 iMenuObserver->HandleAttemptDimmedSelectionL( command ); |
|
4241 } |
|
4242 return ETrue; |
|
4243 } |
|
4244 } |
|
4245 return EFalse; |
|
4246 } |
|
4247 |
|
4248 // ----------------------------------------------------------------------------- |
|
4249 // CEikMenuPane::OfferKeyEventL |
|
4250 // ----------------------------------------------------------------------------- |
|
4251 // |
|
4252 EXPORT_C TKeyResponse CEikMenuPane::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType ) |
|
4253 { // if were on the control stack then consume all keys |
|
4254 return OfferKeyEventL( aKeyEvent, aType, ETrue ); |
|
4255 } |
|
4256 |
|
4257 // ----------------------------------------------------------------------------- |
|
4258 // CEikMenuPane::OfferKeyEventL |
|
4259 // ----------------------------------------------------------------------------- |
|
4260 // |
|
4261 EXPORT_C TKeyResponse CEikMenuPane::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType, TBool aConsumeAllKeys ) |
|
4262 { |
|
4263 _AKNTRACE_FUNC_ENTER; |
|
4264 // Key event handling for scroll physics |
|
4265 // Don't react to shift keys |
|
4266 if ( aKeyEvent.iScanCode == EStdKeyLeftShift || |
|
4267 aKeyEvent.iScanCode == EStdKeyRightShift ) |
|
4268 { |
|
4269 if ( aConsumeAllKeys ) |
|
4270 { |
|
4271 _AKNTRACE( "[%s]", "OfferKeyEventL return 1" ); |
|
4272 _AKNTRACE_FUNC_EXIT; |
|
4273 return EKeyWasConsumed; |
|
4274 } |
|
4275 else |
|
4276 { |
|
4277 _AKNTRACE( "[%s]", "OfferKeyEventL return 2" ); |
|
4278 _AKNTRACE_FUNC_EXIT; |
|
4279 return EKeyWasNotConsumed; |
|
4280 } |
|
4281 } |
|
4282 // Disable key events when panning |
|
4283 if ( iExtension->iPanningActive || |
|
4284 iExtension->iPhysics->OngoingPhysicsAction() |
|
4285 == CAknPhysics::EAknPhysicsActionBouncing ) |
|
4286 { |
|
4287 _AKNTRACE( "[%s]", "OfferKeyEventL return 3" ); |
|
4288 _AKNTRACE_FUNC_EXIT; |
|
4289 return EKeyWasConsumed; |
|
4290 } |
|
4291 if ( iExtension->iFlickActive ) |
|
4292 { |
|
4293 // Stop physics engine when key down event occurs. |
|
4294 iExtension->iPhysics->StopPhysics(); |
|
4295 iExtension->iPhysics->ResetFriction(); |
|
4296 iExtension->iFlickActive = EFalse; |
|
4297 iExtension->iKeyEventActive = ETrue; |
|
4298 _AKNTRACE( "[%s]", "OfferKeyEventL return 4" ); |
|
4299 _AKNTRACE_FUNC_EXIT; |
|
4300 return EKeyWasConsumed; |
|
4301 } |
|
4302 else if ( iExtension->iKeyEventActive && aType != EEventKeyDown ) |
|
4303 { |
|
4304 // Consume following events until next key down. |
|
4305 _AKNTRACE( "[%s]", "OfferKeyEventL return 5" ); |
|
4306 _AKNTRACE_FUNC_EXIT; |
|
4307 return EKeyWasConsumed; |
|
4308 } |
|
4309 else |
|
4310 { |
|
4311 // Next key down after stopping flick, it is ok to continue. |
|
4312 iExtension->iKeyEventActive = EFalse; |
|
4313 } |
|
4314 |
|
4315 // Restore possible panning offset |
|
4316 if (iExtension->Offset() != 0 ) |
|
4317 { |
|
4318 iExtension->RestoreOffset( aKeyEvent.iCode ); |
|
4319 } |
|
4320 |
|
4321 CheckCreateScrollerL(); |
|
4322 const TInt modifiers = ( aKeyEvent.iModifiers )&( EModifierCtrl|EModifierShift|EModifierPureKeycode ); |
|
4323 const TInt code = aKeyEvent.iCode; |
|
4324 TKeyResponse keyResponse = EKeyWasNotConsumed; |
|
4325 if ( iCascadeMenuPane ) |
|
4326 { |
|
4327 keyResponse = iCascadeMenuPane->OfferKeyEventL( aKeyEvent, aType, EFalse ); |
|
4328 if ( keyResponse == EKeyWasNotConsumed && |
|
4329 ( code==EKeyEscape || (!AknLayoutUtils::LayoutMirrored() && code==EKeyLeftArrow) || ( AknLayoutUtils::LayoutMirrored() && code==EKeyRightArrow) ) ) |
|
4330 { |
|
4331 // show transition only when "canceling" the cascade menu |
|
4332 // choosing an item from cascade does not execute effect |
|
4333 iExtension->iShowCascadeTransition = ETrue; |
|
4334 CloseCascadeMenu(); |
|
4335 //Fixed for TSW errors DLAN-7SFH86. |
|
4336 IgnoreEventsUntilNextPointerUp(); |
|
4337 keyResponse = EKeyWasConsumed; |
|
4338 } |
|
4339 _AKNTRACE( "[%s]", "OfferKeyEventL return 6" ); |
|
4340 _AKNTRACE_FUNC_EXIT; |
|
4341 return keyResponse; |
|
4342 } |
|
4343 |
|
4344 // with single click first key event enables highlight |
|
4345 if ( !iExtension->HighlightEnabled() ) |
|
4346 { |
|
4347 if ( code == EKeyUpArrow || code == EKeyDownArrow || |
|
4348 code == EKeyEnter || code == EKeyOK ) |
|
4349 { |
|
4350 iExtension->SetDefaultHighlight(); |
|
4351 return EKeyWasConsumed; |
|
4352 } |
|
4353 } |
|
4354 |
|
4355 // if popup menu displaying, needs to check for hotkeys itself. |
|
4356 if ( IsHotKeyL( modifiers, code ) ) |
|
4357 return EKeyWasConsumed; |
|
4358 TInt count = 0; |
|
4359 if( iItemArray ) |
|
4360 count = iItemArray->Count(); |
|
4361 if ( count == 0 ) |
|
4362 { |
|
4363 _AKNTRACE( "[%s]", "OfferKeyEventL return 8" ); |
|
4364 _AKNTRACE_FUNC_EXIT; |
|
4365 return EKeyWasNotConsumed; |
|
4366 } |
|
4367 const TInt max = count-1; |
|
4368 TInt newHighlight = iSelectedItem; |
|
4369 TBool loopScrolling = ETrue; |
|
4370 TInt itemAfterLastItem = loopScrolling ? 0 : max; |
|
4371 TInt itemAfterFirstItem = loopScrolling ? max : 0; |
|
4372 |
|
4373 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4374 CWindowGc& gc = iExtension->iGc ? *iExtension->iGc : SystemGc(); |
|
4375 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &gc ); |
|
4376 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
4377 |
|
4378 if(iExtension->iIsPenEnable) |
|
4379 { |
|
4380 _AKNTRACE( "[%s]", "iExtension->iIsPenEnable = TRUE" ); |
|
4381 // Scroll highlighted item so that it becomes visible, |
|
4382 // if it is not visible before (scrolling with scroll bar |
|
4383 // can cause highlighted item to go out of screen) |
|
4384 TInt topItem = iScroller->TopItemIndex(); |
|
4385 TInt bottomItem = topItem + NumberOfItemsThatFitInView(); |
|
4386 |
|
4387 if ( iExtension->Offset() < 0 ) |
|
4388 { |
|
4389 // Extra bottom item when panning |
|
4390 bottomItem++; |
|
4391 } |
|
4392 |
|
4393 if( bottomItem > NumberOfItemsInPane() ) |
|
4394 { |
|
4395 bottomItem = NumberOfItemsInPane(); |
|
4396 } |
|
4397 _AKNTRACE( "topItem = %d,bottomItem = %d", topItem,bottomItem ); |
|
4398 |
|
4399 if ( aType != EEventKeyDown && iSelectedItem != ENothingSelected && |
|
4400 !(iExtension->iSctHighlighted && topItem == 0) && |
|
4401 (iSelectedItem < topItem || iSelectedItem > bottomItem - 1) ) |
|
4402 { |
|
4403 _AKNTRACE( "[%s]", "ScrollToMakeItemVisible(iSelectedItem);" ); |
|
4404 ScrollToMakeItemVisible(iSelectedItem); |
|
4405 |
|
4406 ActivateGc(); |
|
4407 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4408 if ( transApi ) |
|
4409 { |
|
4410 iExtension->iGc->Activate( *DrawableWindow() ); |
|
4411 } |
|
4412 #else |
|
4413 CWindowGc& gc = SystemGc(); |
|
4414 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4415 PrepareGcForDrawingItems( gc ); |
|
4416 |
|
4417 // draw all items that are needed. |
|
4418 for( TInt i = 0; i < count; i++ ) |
|
4419 { |
|
4420 if( i == iSelectedItem && !iExtension->iSctHighlighted) |
|
4421 { |
|
4422 DrawItem( gc, i, EDrawHighlight ); |
|
4423 } |
|
4424 else |
|
4425 { |
|
4426 DrawItem( gc, i, ERemoveHighlight ); |
|
4427 } |
|
4428 } |
|
4429 |
|
4430 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4431 if ( transApi ) |
|
4432 { |
|
4433 iExtension->iGc->Deactivate(); |
|
4434 } |
|
4435 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4436 DeactivateGc(); |
|
4437 _AKNTRACE( "[%s]", "OfferKeyEventL return 9" ); |
|
4438 _AKNTRACE_FUNC_EXIT; |
|
4439 return EKeyWasConsumed; |
|
4440 } |
|
4441 } |
|
4442 |
|
4443 if ( iSelectedItem != ENothingSelected || iExtension->iSctHighlighted ) |
|
4444 { |
|
4445 switch ( code ) |
|
4446 { |
|
4447 case EKeySpace: |
|
4448 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeySpace)" ); |
|
4449 iEikonEnv->InfoMsg( R_EIK_TBUF_PRESS_SPACE_MENP ); |
|
4450 _AKNTRACE( "[%s]", "OfferKeyEventL return 10" ); |
|
4451 _AKNTRACE_FUNC_EXIT; |
|
4452 return EKeyWasConsumed; |
|
4453 // AKNLAF start |
|
4454 // loop scrolling always used in options menus |
|
4455 case EKeyDownArrow: |
|
4456 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyDownArrow)" ); |
|
4457 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4458 if ( transApi ) |
|
4459 { |
|
4460 transApi->SetMoveType( |
|
4461 MAknListBoxTfxInternal::EListMoveDown ); |
|
4462 } |
|
4463 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
4464 if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4465 { |
|
4466 iExtension->iSctHighlighted = EFalse; |
|
4467 MoveHighlightTo( ++newHighlight ); |
|
4468 iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); |
|
4469 } |
|
4470 else |
|
4471 { |
|
4472 if ( iSelectedItem == max && iExtension->iSct) |
|
4473 { |
|
4474 // If SCT exists, it gets the highlight |
|
4475 // if moving from the bottom item |
|
4476 iExtension->iSctHighlighted = ETrue; |
|
4477 MoveHighlightTo( ENothingSelected ); |
|
4478 iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); |
|
4479 } |
|
4480 else |
|
4481 { |
|
4482 MoveHighlightTo( ++newHighlight>max? itemAfterLastItem: newHighlight ); |
|
4483 } |
|
4484 } |
|
4485 keyResponse = EKeyWasConsumed; |
|
4486 break; |
|
4487 case EKeyUpArrow: |
|
4488 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyUpArrow)" ); |
|
4489 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4490 if ( transApi ) |
|
4491 { |
|
4492 transApi->SetMoveType( |
|
4493 MAknListBoxTfxInternal::EListMoveUp ); |
|
4494 } |
|
4495 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
4496 if ( iExtension->iSct && |
|
4497 iSelectedItem == 0 && !iExtension->iSctHighlighted ) |
|
4498 { |
|
4499 iExtension->iSctHighlighted = ETrue; |
|
4500 MoveHighlightTo( ENothingSelected ); |
|
4501 iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); |
|
4502 } |
|
4503 else if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4504 { |
|
4505 iExtension->iSctHighlighted = EFalse; |
|
4506 MoveHighlightTo( itemAfterFirstItem ); |
|
4507 iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); |
|
4508 } |
|
4509 else |
|
4510 { |
|
4511 MoveHighlightTo( --newHighlight<0? |
|
4512 itemAfterFirstItem: newHighlight ); |
|
4513 } |
|
4514 keyResponse = EKeyWasConsumed; |
|
4515 break; |
|
4516 // AKNLAF end |
|
4517 case EKeyRightArrow : |
|
4518 case EKeyLeftArrow : |
|
4519 { |
|
4520 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyRightArrow or EKeyLeftArrow)" ); |
|
4521 if( count == 0 ) // Implies empty or undefined item array |
|
4522 { |
|
4523 if ( aConsumeAllKeys ) |
|
4524 return EKeyWasConsumed; |
|
4525 return EKeyWasNotConsumed; |
|
4526 } |
|
4527 if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4528 { |
|
4529 return iExtension->iSct->OfferKeyEventL( aKeyEvent, aType ); |
|
4530 } |
|
4531 const CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem]; |
|
4532 |
|
4533 if ( item->iData.iCascadeId && iExtension->HighlightEnabled() ) |
|
4534 { |
|
4535 if ( ( !AknLayoutUtils::LayoutMirrored() && code == EKeyRightArrow ) || |
|
4536 ( AknLayoutUtils::LayoutMirrored() && code == EKeyLeftArrow ) ) |
|
4537 { |
|
4538 TryLaunchCascadeMenuL( *item ); |
|
4539 |
|
4540 if ( iCascadeMenuPane ) |
|
4541 { |
|
4542 iCascadeMenuPane->iExtension->SetDefaultHighlight(); |
|
4543 } |
|
4544 |
|
4545 keyResponse = EKeyWasConsumed; |
|
4546 break; |
|
4547 } // else fall through |
|
4548 } // else fall through |
|
4549 } |
|
4550 case EKeyHome: |
|
4551 case EKeyEnd: |
|
4552 { |
|
4553 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyHome or EKeyEnd)" ); |
|
4554 // only popup menu panes should consume these keys. ??? |
|
4555 if ( aConsumeAllKeys ) |
|
4556 return EKeyWasConsumed; |
|
4557 return EKeyWasNotConsumed; |
|
4558 } |
|
4559 case EKeyEnter: |
|
4560 case EKeyOK: |
|
4561 case EAknSoftkeySelect: |
|
4562 case EAknSoftkeyOk: |
|
4563 |
|
4564 { |
|
4565 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyEnter,EKeyOK,EAknSoftkeySelect,EAknSoftkeyOk)" ); |
|
4566 if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4567 { |
|
4568 keyResponse = iExtension->iSct->OfferKeyEventL( aKeyEvent, aType ); |
|
4569 if ( keyResponse == EKeyWasConsumed ) |
|
4570 { |
|
4571 ReportSelectionMadeL(); |
|
4572 break; |
|
4573 } |
|
4574 } |
|
4575 if ( modifiers&( EModifierShift|EModifierCtrl|EModifierFunc ) ) |
|
4576 return EKeyWasConsumed; |
|
4577 if ( aKeyEvent.iRepeats ) |
|
4578 return EKeyWasConsumed; |
|
4579 if ( count == 0 ) // Do the same as modifiers (implies empty or undefined item array) |
|
4580 return EKeyWasConsumed; |
|
4581 CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem]; |
|
4582 if ( item->iData.iCascadeId ) |
|
4583 { |
|
4584 TryLaunchCascadeMenuL( *item ); |
|
4585 if ( iCascadeMenuPane ) |
|
4586 { |
|
4587 iCascadeMenuPane->iExtension->SetDefaultHighlight(); |
|
4588 } |
|
4589 } |
|
4590 else |
|
4591 ReportSelectionMadeL(); |
|
4592 return EKeyWasConsumed; |
|
4593 } |
|
4594 case '4':// These are for menu sct. |
|
4595 case '5': |
|
4596 case '6': |
|
4597 { |
|
4598 _AKNTRACE( "[%s]", "OfferKeyEventL('4','5','6')" ); |
|
4599 if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4600 { |
|
4601 return iExtension->iSct->OfferKeyEventL( aKeyEvent, aType ); |
|
4602 } |
|
4603 else |
|
4604 { |
|
4605 return EKeyWasNotConsumed; |
|
4606 } |
|
4607 } |
|
4608 |
|
4609 default: |
|
4610 break; |
|
4611 } |
|
4612 } |
|
4613 |
|
4614 switch ( code ) |
|
4615 { |
|
4616 case EKeyMenu: |
|
4617 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyMenu)" ); |
|
4618 iMenuObserver->HandleSideBarMenuL( 0, TPoint( 0, 0 ), modifiers, iHotKeyTable ); |
|
4619 return EKeyWasConsumed; |
|
4620 case EKeyEscape: |
|
4621 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyEscape)" ); |
|
4622 if ( iOwner ) |
|
4623 return EKeyWasNotConsumed; // owner will destroy the cascade |
|
4624 ReportCanceled(); |
|
4625 return EKeyWasConsumed; |
|
4626 default: |
|
4627 break; |
|
4628 } |
|
4629 |
|
4630 if ( MoveToItemL( code, modifiers) ) |
|
4631 { |
|
4632 _AKNTRACE( "[%s]", "OfferKeyEventL return 11" ); |
|
4633 _AKNTRACE_FUNC_EXIT; |
|
4634 return EKeyWasConsumed; // must return here because in the case of a cascade it will have been deleted by now. |
|
4635 } |
|
4636 |
|
4637 if ( aConsumeAllKeys ) |
|
4638 { |
|
4639 _AKNTRACE( "[%s]", "OfferKeyEventL return 12" ); |
|
4640 _AKNTRACE_FUNC_EXIT; |
|
4641 return EKeyWasConsumed; |
|
4642 } |
|
4643 |
|
4644 else |
|
4645 { |
|
4646 _AKNTRACE( "[%s]", "OfferKeyEventL return 13" ); |
|
4647 _AKNTRACE_FUNC_EXIT; |
|
4648 return keyResponse; |
|
4649 } |
|
4650 } |
|
4651 |
|
4652 |
|
4653 // ----------------------------------------------------------------------------- |
|
4654 // CEikMenuPane::NavigateToNextItem |
|
4655 // New for AVKON |
|
4656 // ----------------------------------------------------------------------------- |
|
4657 // |
|
4658 EXPORT_C void CEikMenuPane::NavigateToNextItem() |
|
4659 { |
|
4660 if ( iCascadeMenuPane ) |
|
4661 iCascadeMenuPane->NavigateToNextItem(); |
|
4662 else |
|
4663 { |
|
4664 const TInt max = NumberOfItemsInPane() - 1; |
|
4665 TInt newHighlight = SelectedItem(); |
|
4666 MoveHighlightTo( ( ++newHighlight > max ) ? 0 : newHighlight); |
|
4667 } |
|
4668 } |
|
4669 |
|
4670 |
|
4671 // --------------------------------------------------------------------------- |
|
4672 // Activates the currently highlighted item. |
|
4673 // --------------------------------------------------------------------------- |
|
4674 // |
|
4675 void CEikMenuPane::ActivateCurrentItemL() |
|
4676 { |
|
4677 if ( !iExtension->HighlightEnabled() ) |
|
4678 { |
|
4679 iExtension->SetDefaultHighlight(); |
|
4680 return; |
|
4681 } |
|
4682 _AKNTRACE_FUNC_ENTER; |
|
4683 |
|
4684 if ( iExtension->iPanningActive || |
|
4685 iExtension->iPhysics->OngoingPhysicsAction() |
|
4686 == CAknPhysics::EAknPhysicsActionBouncing ) |
|
4687 { |
|
4688 // Don't allow the item activation in kinetic scrolling enabled |
|
4689 // menus if menu is being dragged or bounce effect is in action. |
|
4690 // In this case the event is discarded. |
|
4691 _AKNTRACE( "[%s]" "ActivateCurrentItemL return 1" ); |
|
4692 _AKNTRACE_FUNC_EXIT; |
|
4693 return; |
|
4694 } |
|
4695 |
|
4696 TInt count( NumberOfItemsInPane() ); |
|
4697 |
|
4698 if ( iExtension->iIsPenEnable ) |
|
4699 { |
|
4700 // Scroll highlighted item so that it becomes visible |
|
4701 // if it is not visible before (scrolling with scroll bar |
|
4702 // can cause highlighted item to go out of screen). |
|
4703 TInt topItem( iScroller->TopItemIndex() ); |
|
4704 TInt bottomItem( topItem + NumberOfItemsThatFitInView() ); |
|
4705 if ( bottomItem > count ) |
|
4706 { |
|
4707 bottomItem = count; |
|
4708 } |
|
4709 |
|
4710 if ( iExtension->Offset() < 0 && |
|
4711 ( iSelectedItem == topItem || iSelectedItem == bottomItem ) ) |
|
4712 { |
|
4713 // Restoring offset with "simulated" ok key event. |
|
4714 iExtension->RestoreOffset( EKeyOK ); |
|
4715 } |
|
4716 else if ( iSelectedItem < topItem || |
|
4717 iSelectedItem > bottomItem - 1 ) |
|
4718 { |
|
4719 if ( count > iSelectedItem ) |
|
4720 { |
|
4721 if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4722 { |
|
4723 TKeyEvent key; |
|
4724 key.iCode = EKeyOK; |
|
4725 key.iModifiers = 0; |
|
4726 |
|
4727 TKeyResponse keyResponse( EKeyWasNotConsumed ); |
|
4728 TEventCode type( EEventNull ); |
|
4729 keyResponse = iExtension->iSct->OfferKeyEventL( key, |
|
4730 type ); |
|
4731 if ( keyResponse == EKeyWasConsumed ) |
|
4732 { |
|
4733 ReportSelectionMadeL(); |
|
4734 } |
|
4735 _AKNTRACE( "[%s]" "ActivateCurrentItemL return 2" ); |
|
4736 _AKNTRACE_FUNC_EXIT; |
|
4737 return; |
|
4738 } |
|
4739 } |
|
4740 |
|
4741 iExtension->isUpdateScrollDirectly = ETrue; |
|
4742 ScrollToMakeItemVisible( iSelectedItem ); |
|
4743 iExtension->isUpdateScrollDirectly = EFalse; |
|
4744 |
|
4745 ActivateGc(); |
|
4746 |
|
4747 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4748 |
|
4749 MAknListBoxTfxInternal *transApi = |
|
4750 CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
4751 if ( transApi ) |
|
4752 { |
|
4753 iExtension->iGc->Activate( *DrawableWindow() ); |
|
4754 } |
|
4755 CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc(); |
|
4756 |
|
4757 #else |
|
4758 |
|
4759 CWindowGc& gc = SystemGc(); |
|
4760 |
|
4761 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4762 |
|
4763 PrepareGcForDrawingItems( gc ); |
|
4764 |
|
4765 // Draw all items that are needed. |
|
4766 for ( TInt i = 0; i < count; i++ ) |
|
4767 { |
|
4768 if ( i == iSelectedItem && !iExtension->iSctHighlighted ) |
|
4769 { |
|
4770 DrawItem( gc, i, EDrawHighlight ); |
|
4771 } |
|
4772 else |
|
4773 { |
|
4774 DrawItem( gc, i, ERemoveHighlight ); |
|
4775 } |
|
4776 } |
|
4777 |
|
4778 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4779 |
|
4780 if ( transApi ) |
|
4781 { |
|
4782 iExtension->iGc->Deactivate(); |
|
4783 } |
|
4784 |
|
4785 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4786 |
|
4787 DeactivateGc(); |
|
4788 _AKNTRACE( "[%s]" "ActivateCurrentItemL return 3" ); |
|
4789 _AKNTRACE_FUNC_EXIT; |
|
4790 return; |
|
4791 } |
|
4792 } |
|
4793 |
|
4794 if ( iCascadeMenuPane ) |
|
4795 { |
|
4796 iCascadeMenuPane->ActivateCurrentItemL(); |
|
4797 } |
|
4798 else |
|
4799 { |
|
4800 if ( count > iSelectedItem ) |
|
4801 { |
|
4802 if ( iExtension->iSctHighlighted && iExtension->iSct ) |
|
4803 { |
|
4804 TKeyEvent key; |
|
4805 key.iCode = EKeyOK; |
|
4806 key.iModifiers = 0; |
|
4807 |
|
4808 TKeyResponse keyResponse( EKeyWasNotConsumed ); |
|
4809 TEventCode type( EEventNull ); |
|
4810 keyResponse = iExtension->iSct->OfferKeyEventL( |
|
4811 key, type ); |
|
4812 if ( keyResponse == EKeyWasConsumed ) |
|
4813 { |
|
4814 ReportSelectionMadeL(); |
|
4815 } |
|
4816 } |
|
4817 else |
|
4818 { |
|
4819 CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem]; |
|
4820 if ( item->iData.iCascadeId ) |
|
4821 { |
|
4822 TryLaunchCascadeMenuL(*item); |
|
4823 } |
|
4824 else |
|
4825 { |
|
4826 ReportSelectionMadeL(); |
|
4827 } |
|
4828 } |
|
4829 } |
|
4830 } |
|
4831 _AKNTRACE( "[%s]" "ActivateCurrentItemL return 4" ); |
|
4832 _AKNTRACE_FUNC_EXIT; |
|
4833 } |
|
4834 |
|
4835 |
|
4836 // ----------------------------------------------------------------------------- |
|
4837 // CEikMenuPane::CancelActiveMenuPane |
|
4838 // New for AVKON |
|
4839 // ----------------------------------------------------------------------------- |
|
4840 // |
|
4841 TBool CEikMenuPane::CancelActiveMenuPane() |
|
4842 { |
|
4843 // If it is possible to close a cascade, return ETrue |
|
4844 if ( iCascadeMenuPane ) |
|
4845 { |
|
4846 iCascadeMenuPane->CancelActiveMenuPane(); |
|
4847 CloseCascadeMenu( ETrue ); |
|
4848 return ETrue; |
|
4849 } |
|
4850 return EFalse; |
|
4851 } |
|
4852 |
|
4853 // ----------------------------------------------------------------------------- |
|
4854 // CEikMenuPane::MoveToItemL |
|
4855 // ----------------------------------------------------------------------------- |
|
4856 // |
|
4857 TBool CEikMenuPane::MoveToItemL(TInt /*aCode*/, TInt /*aMods*/) |
|
4858 { |
|
4859 return EFalse; |
|
4860 } |
|
4861 |
|
4862 // ----------------------------------------------------------------------------- |
|
4863 // CEikMenuPane::ReportCanceled |
|
4864 // ----------------------------------------------------------------------------- |
|
4865 // |
|
4866 void CEikMenuPane::ReportCanceled() |
|
4867 { |
|
4868 |
|
4869 // let menubar handle the cancel case so transition can be shown |
|
4870 // use "fake" pointer event |
|
4871 CEikMenuBar* menubar = static_cast<CEikMenuBar*>( Parent() ); |
|
4872 if( menubar->MenuPane() == this ) |
|
4873 { |
|
4874 TPointerEvent ptrEvent; |
|
4875 ptrEvent.iType = TPointerEvent::EButton1Up; |
|
4876 menubar->HandlePointerEventL( ptrEvent ); |
|
4877 } |
|
4878 else |
|
4879 { |
|
4880 MCoeControlObserver* observer = iOwner ? iOwner->Observer() : Observer(); |
|
4881 if ( observer ) |
|
4882 { |
|
4883 // context sensitive menu |
|
4884 TRAP_IGNORE( observer->HandleControlEventL( iOwner ? iOwner : this, |
|
4885 MCoeControlObserver::EEventRequestCancel ) ); |
|
4886 } |
|
4887 else |
|
4888 { |
|
4889 // application menu |
|
4890 TRAP_IGNORE( iMenuObserver->ProcessCommandL( EEikCmdCanceled ) ); |
|
4891 } |
|
4892 } |
|
4893 } |
|
4894 |
|
4895 // ----------------------------------------------------------------------------- |
|
4896 // CEikMenuPane::ExtensionInterface |
|
4897 // ----------------------------------------------------------------------------- |
|
4898 // |
|
4899 EXPORT_C void* CEikMenuPane::ExtensionInterface( TUid /*aInterface*/ ) |
|
4900 { |
|
4901 return NULL; |
|
4902 } |
|
4903 |
|
4904 // ---------------------------------------------------------------------------- |
|
4905 // CEikMenuPane::HandlePointerEventL |
|
4906 // |
|
4907 // Handles pointer events. |
|
4908 // ---------------------------------------------------------------------------- |
|
4909 // |
|
4910 EXPORT_C void CEikMenuPane::HandlePointerEventL( const TPointerEvent& aPointerEvent ) |
|
4911 { |
|
4912 if( !AknLayoutUtils::PenEnabled() ) |
|
4913 { |
|
4914 return; |
|
4915 } |
|
4916 |
|
4917 _AKNTRACE_FUNC_ENTER; |
|
4918 |
|
4919 if ( iOwner && !IsVisible() ) |
|
4920 { |
|
4921 _AKNTRACE( "[%s]", "HandlePointerEventL return 1" ); |
|
4922 _AKNTRACE_FUNC_EXIT; |
|
4923 return; |
|
4924 } |
|
4925 |
|
4926 TBool noSelection = EFalse; |
|
4927 |
|
4928 // get pointer grabber1 |
|
4929 CCoeControl* grabberBefore = GrabbingComponent(); |
|
4930 |
|
4931 TPointerEvent pointerEvent = aPointerEvent; |
|
4932 iExtension->ChangePosition( pointerEvent ); |
|
4933 iExtension->iLastPointerEvent = pointerEvent; |
|
4934 |
|
4935 // Send pointerevent to childs - not to scroll bar if a sub menu is open |
|
4936 TRect sbRect; |
|
4937 if ( iSBFrame->VerticalScrollBar() && |
|
4938 iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn ) |
|
4939 { |
|
4940 sbRect = iSBFrame->VerticalScrollBar()->Rect(); |
|
4941 } |
|
4942 if ( ! ( iCascadeMenuPane && sbRect.Contains( |
|
4943 pointerEvent.iPosition ) ) ) |
|
4944 { |
|
4945 _AKNTRACE( "[%s]", "CAknControl::HandlePointerEventL( pointerEvent );" ); |
|
4946 CAknControl::HandlePointerEventL( pointerEvent ); |
|
4947 } |
|
4948 else |
|
4949 { |
|
4950 if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) |
|
4951 { |
|
4952 if( AknLayoutUtils::PenEnabled() ) |
|
4953 { |
|
4954 if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) |
|
4955 { |
|
4956 iExtension->ImmediateFeedback( ETouchFeedbackDecreasingPopUp ); |
|
4957 } |
|
4958 else |
|
4959 { |
|
4960 iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); |
|
4961 } |
|
4962 } |
|
4963 iExtension->iShowCascadeTransition = ETrue; |
|
4964 CloseCascadeMenu(); |
|
4965 IgnoreEventsUntilNextPointerUp(); |
|
4966 _AKNTRACE( "[%s]", "HandlePointerEventL return 2" ); |
|
4967 _AKNTRACE_FUNC_EXIT; |
|
4968 return; |
|
4969 } |
|
4970 } |
|
4971 |
|
4972 // get pointer grabber |
|
4973 CCoeControl* grabberAfter = GrabbingComponent(); |
|
4974 |
|
4975 // if grabberBefore or grabberAfter, then some child is handling pointerevent. |
|
4976 if ( (grabberBefore || grabberAfter ) |
|
4977 && ( !iExtension->iSct || iExtension->iScrollBarRect.Contains( pointerEvent.iPosition ) ) ) |
|
4978 { |
|
4979 _AKNTRACE( "[%s]", "HandlePointerEventL return 3" ); |
|
4980 _AKNTRACE_FUNC_EXIT; |
|
4981 return; |
|
4982 } |
|
4983 |
|
4984 // Forward pointer events to embedded CBA if sub menu open |
|
4985 if ( iExtension->iCba && iCascadeMenuPane ) |
|
4986 { |
|
4987 TBool sendToCBA = EFalse; |
|
4988 // if embedded CBA is grabbing the pointer we send the events to it |
|
4989 if( iExtension->iDownOnCbaArea ) |
|
4990 { |
|
4991 if( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
4992 { |
|
4993 iExtension->iDownOnCbaArea = EFalse; |
|
4994 } |
|
4995 sendToCBA = ETrue; |
|
4996 } |
|
4997 else |
|
4998 { |
|
4999 TPoint pos ( |
|
5000 aPointerEvent.iPosition + PositionRelativeToScreen() ); |
|
5001 TRect cbaRect ( iExtension->iCba->PositionRelativeToScreen(), |
|
5002 iExtension->iCba->Size() ); |
|
5003 if ( cbaRect.Contains( pos ) && |
|
5004 aPointerEvent.iType == TPointerEvent::EButton1Down ) |
|
5005 { |
|
5006 sendToCBA = ETrue; |
|
5007 iExtension->iDownOnCbaArea = ETrue; |
|
5008 } |
|
5009 } |
|
5010 iCascadeMenuPane->iExtension->iDownOnCbaArea |
|
5011 = iExtension->iDownOnCbaArea; |
|
5012 |
|
5013 if ( sendToCBA ) |
|
5014 { |
|
5015 // scale the pointer event coordinates relative to CBA |
|
5016 TPointerEvent event = aPointerEvent; |
|
5017 TPoint position( aPointerEvent.iPosition + |
|
5018 PositionRelativeToScreen() ); |
|
5019 event.iPosition = (position - |
|
5020 iExtension->iCba->PositionRelativeToScreen()); |
|
5021 // send the event to CBA |
|
5022 iExtension->iCba->HandlePointerEventL(event); |
|
5023 _AKNTRACE( "[%s]", "HandlePointerEventL return 4" ); |
|
5024 _AKNTRACE_FUNC_EXIT; |
|
5025 return; |
|
5026 } |
|
5027 } |
|
5028 // Submenu of a submenu to forward events to cba |
|
5029 else if ( iCascadeMenuPane ) |
|
5030 { |
|
5031 iCascadeMenuPane->iExtension->iDownOnCbaArea |
|
5032 = iExtension->iDownOnCbaArea; |
|
5033 } |
|
5034 |
|
5035 // In sub menu and pointer down has come to cba area |
|
5036 if ( iOwner && iOwner->iExtension->iDownOnCbaArea ) |
|
5037 { |
|
5038 TPointerEvent parentEvent; |
|
5039 iExtension->CalculateParentEvent(aPointerEvent, parentEvent); |
|
5040 _AKNTRACE( "[%s]", "HandlePointerEventL return 5" ); |
|
5041 _AKNTRACE_FUNC_EXIT; |
|
5042 return iOwner->HandlePointerEventL( parentEvent ); |
|
5043 } |
|
5044 |
|
5045 // Rect whic contains only area of menu items. |
|
5046 const TRect innerRect = iBorder.InnerRect( Rect() ); |
|
5047 TRect menuSctRect; |
|
5048 // Get the option item's rect in Menu SCT |
|
5049 if ( iExtension->iSct ) |
|
5050 { |
|
5051 TAknLayoutRect menuPaneRect; |
|
5052 TAknWindowLineLayout menuPane; |
|
5053 |
|
5054 TAknWindowLineLayout listScrollPaneLayout( |
|
5055 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
5056 if ( iExtension ) |
|
5057 { |
|
5058 iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); |
|
5059 } |
|
5060 TAknLayoutRect listScrollPaneRect; |
|
5061 listScrollPaneRect.LayoutRect( Rect(), listScrollPaneLayout ); |
|
5062 |
|
5063 menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); |
|
5064 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
5065 menuSctRect = menuPaneRect.Rect(); |
|
5066 } |
|
5067 TRect cascadeMenuRect(0,0,0,0); |
|
5068 |
|
5069 // Y coordinate for pointer event |
|
5070 const TInt yPos = aPointerEvent.iPosition.iY; |
|
5071 |
|
5072 |
|
5073 // Get top and botton item indexes. |
|
5074 TInt topItem = iScroller->TopItemIndex(); |
|
5075 TInt bottomItem = topItem + NumberOfItemsThatFitInView(); |
|
5076 |
|
5077 if( iExtension->Offset() < 0 ) |
|
5078 { |
|
5079 // Panning has happened so we have one extra item. |
|
5080 ++bottomItem; |
|
5081 } |
|
5082 |
|
5083 if( bottomItem > NumberOfItemsInPane() ) |
|
5084 { |
|
5085 bottomItem = NumberOfItemsInPane(); |
|
5086 } |
|
5087 |
|
5088 |
|
5089 // if submenu, then move it's rect coordinates to relative to parent. |
|
5090 if ( iCascadeMenuPane ) |
|
5091 { |
|
5092 TPoint subPos = iCascadeMenuPane->PositionRelativeToScreen(); |
|
5093 cascadeMenuRect = TRect(subPos-PositionRelativeToScreen(), iCascadeMenuPane->Size()); |
|
5094 } |
|
5095 |
|
5096 // Pointerevent in case we need to pass event from submenu to parent |
|
5097 TPointerEvent parentEvent; |
|
5098 |
|
5099 // Stop timers if dragged outside |
|
5100 if ( iExtension && iExtension->iDraggedOutside ) |
|
5101 { |
|
5102 iExtension->StopCascadeMenuTimer(); |
|
5103 iExtension->ResetPressedHighlight(); |
|
5104 } |
|
5105 |
|
5106 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5107 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( |
|
5108 iExtension->iGc ); |
|
5109 TBool effects = transApi && !transApi->EffectsDisabled(); |
|
5110 #endif |
|
5111 |
|
5112 switch (aPointerEvent.iType ) |
|
5113 { |
|
5114 case TPointerEvent::EButton1Up: |
|
5115 { |
|
5116 _AKNTRACE( "[%s]", "TPointerEvent::EButton1Up" ); |
|
5117 if ( !innerRect.Contains( aPointerEvent.iPosition ) ) |
|
5118 { |
|
5119 // remove highlight in case highlight is outside of menu pane |
|
5120 iExtension->EnableHighlight( EFalse ); |
|
5121 if ( iOwner ) |
|
5122 { |
|
5123 RepaintHighlight(); |
|
5124 } |
|
5125 } |
|
5126 if ( iOwner && |
|
5127 !innerRect.Contains( aPointerEvent.iPosition ) && |
|
5128 !iExtension->iDownOnMenuArea ) |
|
5129 { |
|
5130 iExtension->CalculateParentEvent( aPointerEvent, parentEvent); |
|
5131 _AKNTRACE( "[%s]", "HandlePointerEventL return 6" ); |
|
5132 _AKNTRACE_FUNC_EXIT; |
|
5133 return iOwner->HandlePointerEventL( parentEvent ); |
|
5134 } |
|
5135 iExtension->iDownOnMenuArea = EFalse; |
|
5136 |
|
5137 iExtension->iPanningActive = EFalse; |
|
5138 if ( !(iExtension->iSct && iExtension->iSct->Rect().Contains( iExtension->iStartPoint ) ) ) |
|
5139 { |
|
5140 TPoint drag = iExtension->iStartPoint - aPointerEvent.iPosition; |
|
5141 if ( iExtension->iPhysics->StartPhysics( |
|
5142 drag, iExtension->iStartTime ) ) |
|
5143 { |
|
5144 iExtension->iFlickActive = ETrue; |
|
5145 iExtension->ResetPressedHighlight(); |
|
5146 } |
|
5147 } |
|
5148 if ( iExtension->HighlightTimerActive() && |
|
5149 !iExtension->iPressedDown ) |
|
5150 { |
|
5151 // Complete the timer here if it's still running |
|
5152 // when up event is received. |
|
5153 iExtension->ResetPressedHighlight(); |
|
5154 CEikMenuPaneExtension::HighlightTimerCallBack( iExtension ); |
|
5155 } |
|
5156 |
|
5157 // in submenu and pointer lifted outside of x -limits : handle in parent |
|
5158 if ( iOwner && iOwner->IsFocused() && (aPointerEvent.iPosition.iX < innerRect.iTl.iX || |
|
5159 aPointerEvent.iPosition.iX > innerRect.iBr.iX )) |
|
5160 { |
|
5161 iExtension->CalculateParentEvent( aPointerEvent, parentEvent); |
|
5162 _AKNTRACE( "[%s]", "HandlePointerEventL return 7" ); |
|
5163 _AKNTRACE_FUNC_EXIT; |
|
5164 return iOwner->HandlePointerEventL( parentEvent ); |
|
5165 } |
|
5166 |
|
5167 // if button up inside menu and over selected item, then do selection. |
|
5168 if (Extension()->iItemsReadyForPenSelection && |
|
5169 innerRect.Contains( aPointerEvent.iPosition ) ) |
|
5170 { |
|
5171 |
|
5172 if(iExtension->iSct && iExtension->iSct->Rect().Contains(aPointerEvent.iPosition) && iExtension->iSpecialCharPointed) |
|
5173 { |
|
5174 TKeyEvent key; |
|
5175 key.iCode=EKeyOK; |
|
5176 key.iModifiers=0; |
|
5177 iExtension->iSct->OfferKeyEventL(key, EEventKey); |
|
5178 iExtension->iSpecialCharPointed = EFalse; |
|
5179 Extension()->iItemsReadyForPenSelection = EFalse; |
|
5180 ReportSelectionMadeL(); |
|
5181 _AKNTRACE( "[%s]", "HandlePointerEventL return 8" ); |
|
5182 _AKNTRACE_FUNC_EXIT; |
|
5183 return; |
|
5184 } |
|
5185 else if(iSelectedItem != ENothingSelected ) // beware out of indexing |
|
5186 { |
|
5187 if ( iItemArray->Count() == 0 ) |
|
5188 { |
|
5189 _AKNTRACE( "[%s]", "HandlePointerEventL return 9" ); |
|
5190 _AKNTRACE_FUNC_EXIT; |
|
5191 return; |
|
5192 } |
|
5193 |
|
5194 TInt threshold = 0; |
|
5195 threshold = iExtension->iPhysics->DragThreshold(); |
|
5196 |
|
5197 CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem]; |
|
5198 if((yPos < item->iPos + iItemHeight + threshold ) && |
|
5199 ( yPos > item->iPos - threshold ) ) |
|
5200 { |
|
5201 // if new item has submenu, show it |
|
5202 if ( item->iData.iCascadeId |
|
5203 && iSelectedItem == iExtension->iButtonDownItem ) |
|
5204 { |
|
5205 // close previous submenu if open |
|
5206 if ( iCascadeMenuPane ) |
|
5207 { |
|
5208 CloseCascadeMenu(); |
|
5209 } |
|
5210 iExtension->StopCascadeMenuTimer(); |
|
5211 |
|
5212 iExtension->ResetPressedHighlight(); |
|
5213 |
|
5214 // Up happened on partial item, it must be moved to be |
|
5215 // fully visible before opening (possible) cascade menu. |
|
5216 if( iSelectedItem == topItem || |
|
5217 iSelectedItem == bottomItem - 1) |
|
5218 { |
|
5219 // Restoring physics offset with "simulated" ok key event |
|
5220 iExtension->RestoreOffset( EKeyOK ); |
|
5221 } |
|
5222 MoveHighlightTo(iSelectedItem); |
|
5223 |
|
5224 TryLaunchCascadeMenuL( *item ); |
|
5225 } |
|
5226 else if ( iExtension->iButtonDownItem == iSelectedItem ) |
|
5227 { |
|
5228 iExtension->ImmediateFeedback( ETouchFeedbackList, |
|
5229 ETouchFeedbackVibra ); |
|
5230 if( !IsCascadeMenuPane() ) |
|
5231 { |
|
5232 // EFalse = don't stop transition if opening the cascade menu |
|
5233 // just report selection |
|
5234 if ( ( !iExtension->iSct || ( iExtension->iSct && menuSctRect.Contains( aPointerEvent.iPosition ) ) ) |
|
5235 && !iCascadeMenuPane && iExtension->iPressedDown ) |
|
5236 { |
|
5237 Extension()->iItemsReadyForPenSelection = EFalse; |
|
5238 iExtension->ResetPressedHighlight(); |
|
5239 ReportSelectionMadeL( EFalse ); |
|
5240 _AKNTRACE( "[%s]", "HandlePointerEventL return 10" ); |
|
5241 _AKNTRACE_FUNC_EXIT; |
|
5242 return; |
|
5243 } |
|
5244 } |
|
5245 else |
|
5246 { |
|
5247 if ( !iExtension->iSct || ( iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition) ) |
|
5248 && iExtension->iPressedDown ) |
|
5249 { |
|
5250 Extension()->iItemsReadyForPenSelection = EFalse; |
|
5251 iExtension->ResetPressedHighlight(); |
|
5252 ReportSelectionMadeL(); |
|
5253 _AKNTRACE( "[%s]", "HandlePointerEventL return 11" ); |
|
5254 _AKNTRACE_FUNC_EXIT; |
|
5255 return; |
|
5256 } |
|
5257 } |
|
5258 } |
|
5259 } |
|
5260 } |
|
5261 } |
|
5262 |
|
5263 iExtension->ResetPressedHighlight(); |
|
5264 iExtension->iButtonDownItem = KErrNotFound; |
|
5265 if ( iExtension->iNextHighlightItem != KErrNotFound ) |
|
5266 { |
|
5267 MoveHighlightTo( iExtension->iNextHighlightItem ); |
|
5268 iExtension->iNextHighlightItem = KErrNotFound; |
|
5269 } |
|
5270 } |
|
5271 break; |
|
5272 case TPointerEvent::EButton1Down: |
|
5273 { |
|
5274 _AKNTRACE( "[%s]", "TPointerEvent::EButton1Down" ); |
|
5275 iExtension->iNextHighlightItem = KErrNotFound; |
|
5276 |
|
5277 // Start drag |
|
5278 if( innerRect.Contains( aPointerEvent.iPosition ) ) |
|
5279 { |
|
5280 if ( iExtension->iFlickActive ) |
|
5281 { |
|
5282 noSelection = ETrue; |
|
5283 //when touch down during the flicking, play a basic list feedback |
|
5284 iExtension->ImmediateFeedback( ETouchFeedbackList ); |
|
5285 } |
|
5286 // stop physics for drag |
|
5287 iExtension->iPhysics->StopPhysics(); |
|
5288 iExtension->iPhysics->ResetFriction(); |
|
5289 |
|
5290 iExtension->iStartPoint = aPointerEvent.iPosition; |
|
5291 iExtension->iPrevPoint = iExtension->iStartPoint; |
|
5292 iExtension->iStartTime.HomeTime(); |
|
5293 } |
|
5294 |
|
5295 if ( !noSelection ) |
|
5296 { |
|
5297 Extension()->iItemsReadyForPenSelection = ETrue; |
|
5298 } |
|
5299 if ( innerRect.Contains( aPointerEvent.iPosition ) ) |
|
5300 { |
|
5301 iExtension->iDownOnMenuArea = ETrue; |
|
5302 if ( !noSelection ) |
|
5303 { |
|
5304 iExtension->EnableHighlight( ETrue, ETrue ); |
|
5305 } |
|
5306 if ( iCascadeMenuPane ) |
|
5307 { |
|
5308 // if submenu, and clicked outside of it |
|
5309 if ( !cascadeMenuRect.Contains( aPointerEvent.iPosition ) ) |
|
5310 { |
|
5311 if( AknLayoutUtils::PenEnabled() ) |
|
5312 { |
|
5313 if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) |
|
5314 { |
|
5315 iExtension->ImmediateFeedback( ETouchFeedbackDecreasingPopUp ); |
|
5316 } |
|
5317 else |
|
5318 { |
|
5319 iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); |
|
5320 } |
|
5321 } |
|
5322 //Just close sub menu |
|
5323 iExtension->iShowCascadeTransition = ETrue; |
|
5324 CloseCascadeMenu(); |
|
5325 iExtension->EnableHighlight( EFalse ); |
|
5326 RepaintHighlight(); |
|
5327 IgnoreEventsUntilNextPointerUp(); |
|
5328 break; |
|
5329 } |
|
5330 } |
|
5331 else |
|
5332 { |
|
5333 // menu sct |
|
5334 if(iExtension->iSct&& !iExtension->iSctHighlighted && iExtension->iSct->Rect().Contains(aPointerEvent.iPosition)) |
|
5335 { |
|
5336 iExtension->iSctHighlighted = ETrue; |
|
5337 iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); |
|
5338 MoveHighlightTo( ENothingSelected ); // from other highlight to sct |
|
5339 } |
|
5340 // Act in the rect of option items |
|
5341 else if (!iExtension->iSct || (iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition))) |
|
5342 { |
|
5343 // Scroll only through visible items |
|
5344 for ( TInt ii = topItem; ii < bottomItem; ++ii ) |
|
5345 { |
|
5346 CEikMenuPaneItem* item = (*iItemArray)[ii]; |
|
5347 |
|
5348 // if this item is clicked |
|
5349 if ((yPos < item->iPos + iItemHeight) && |
|
5350 (yPos > item->iPos)) |
|
5351 { |
|
5352 if(iExtension->iSctHighlighted && iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition)) |
|
5353 { |
|
5354 // from sct to normal menu item |
|
5355 iExtension->iSctHighlighted = EFalse; |
|
5356 iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); |
|
5357 } |
|
5358 |
|
5359 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5360 if ( effects ) |
|
5361 { |
|
5362 transApi->SetMoveType( MAknListBoxTfxInternal::EListTap ); |
|
5363 } |
|
5364 #endif |
|
5365 iExtension->iPressedDown = ETrue; |
|
5366 |
|
5367 // Start timer for pressed highlight |
|
5368 if ( !noSelection ) |
|
5369 { |
|
5370 iExtension->ImmediateFeedback( ETouchFeedbackList ); |
|
5371 iExtension->StartHighlightTimerL(); |
|
5372 } |
|
5373 iExtension->iNextHighlightItem = ii; |
|
5374 iExtension->iButtonDownItem = ii; |
|
5375 |
|
5376 // down even on already highlighted item => list feedback |
|
5377 if ( iExtension->iButtonDownItem == iSelectedItem ) |
|
5378 { |
|
5379 iExtension->ImmediateFeedback( ETouchFeedbackList ); |
|
5380 } |
|
5381 if ( noSelection ) |
|
5382 { |
|
5383 iExtension->iButtonDownItem = KErrNotFound; |
|
5384 } |
|
5385 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5386 if ( effects ) |
|
5387 { |
|
5388 transApi->Draw( Rect() ); |
|
5389 } |
|
5390 #endif |
|
5391 // if new item has submenu, show it |
|
5392 if ( item->iData.iCascadeId ) |
|
5393 { |
|
5394 if ( !iExtension->IsCascadeMenuTimerActive() ) |
|
5395 { |
|
5396 iExtension->StartCascadeMenuTimerL(); |
|
5397 } |
|
5398 } |
|
5399 // item found, then break looping |
|
5400 break; |
|
5401 } |
|
5402 } |
|
5403 } |
|
5404 } |
|
5405 } |
|
5406 else |
|
5407 { |
|
5408 // Clicked out side submenu, parent handles this |
|
5409 if ( iOwner ) |
|
5410 { |
|
5411 iExtension->CalculateParentEvent(aPointerEvent, parentEvent); |
|
5412 _AKNTRACE( "[%s]", "HandlePointerEventL return 12" ); |
|
5413 _AKNTRACE_FUNC_EXIT; |
|
5414 return iOwner->HandlePointerEventL( parentEvent ); |
|
5415 } |
|
5416 else |
|
5417 { |
|
5418 if ( iExtension->iIsPenEnable ) |
|
5419 { |
|
5420 // For finger usability, extend to the right. |
|
5421 TRect innerToRightRect; |
|
5422 if ( AknLayoutUtils::LayoutMirrored() ) |
|
5423 { |
|
5424 innerToRightRect = TRect( Rect().iTl, innerRect.iBr ); |
|
5425 } |
|
5426 else |
|
5427 { |
|
5428 innerToRightRect = TRect( innerRect.iTl, Rect().iBr ); |
|
5429 } |
|
5430 // Keep opened |
|
5431 if ( innerToRightRect.Contains( aPointerEvent.iPosition ) ) |
|
5432 { |
|
5433 break; |
|
5434 } |
|
5435 } |
|
5436 // clicked outside, then close menu case by case |
|
5437 if ( iCascadeMenuPane ) |
|
5438 { |
|
5439 if( AknLayoutUtils::PenEnabled() ) |
|
5440 { |
|
5441 if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) |
|
5442 { |
|
5443 iExtension->ImmediateFeedback( ETouchFeedbackDecreasingPopUp ); |
|
5444 } |
|
5445 else |
|
5446 { |
|
5447 iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); |
|
5448 } |
|
5449 } |
|
5450 iExtension->iShowCascadeTransition = ETrue; |
|
5451 CloseCascadeMenu(); //Just close sub menu. |
|
5452 iExtension->EnableHighlight( EFalse ); |
|
5453 RepaintHighlight(); |
|
5454 IgnoreEventsUntilNextPointerUp(); |
|
5455 } |
|
5456 else |
|
5457 { |
|
5458 ReportCanceled(); //Close main menu. |
|
5459 } |
|
5460 } |
|
5461 } |
|
5462 |
|
5463 } |
|
5464 break; |
|
5465 |
|
5466 case TPointerEvent::EButtonRepeat: |
|
5467 case TPointerEvent::EDrag: |
|
5468 { |
|
5469 _AKNTRACE( "[%s]", "TPointerEvent::EDrag" ); |
|
5470 // In submenu and drag outside and down didn't come to menu |
|
5471 if ( iOwner && |
|
5472 !iExtension->iDownOnMenuArea && |
|
5473 !innerRect.Contains( aPointerEvent.iPosition ) ) |
|
5474 { |
|
5475 iExtension->CalculateParentEvent( aPointerEvent, parentEvent); |
|
5476 _AKNTRACE( "[%s]", "HandlePointerEventL return 13" ); |
|
5477 _AKNTRACE_FUNC_EXIT; |
|
5478 return iOwner->HandlePointerEventL( parentEvent ); |
|
5479 } |
|
5480 |
|
5481 if ( ( iExtension->iSct ) |
|
5482 && ( iExtension->iSct->Rect().Contains( iExtension->iStartPoint ) ) ) |
|
5483 { |
|
5484 break; |
|
5485 } |
|
5486 |
|
5487 TPoint drag = iExtension->iStartPoint - |
|
5488 aPointerEvent.iPosition; |
|
5489 TInt threshold = drag.iY; |
|
5490 if( Abs( threshold ) > iExtension->iPhysics->DragThreshold() ) |
|
5491 { |
|
5492 iExtension->iButtonDownItem = KErrNotFound; |
|
5493 iExtension->ResetPressedHighlight(); |
|
5494 iExtension->iNextHighlightItem = KErrNotFound; |
|
5495 iExtension->iPanningActive = ETrue; |
|
5496 iExtension->EnableHighlight( EFalse ); |
|
5497 |
|
5498 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5499 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc ); |
|
5500 |
|
5501 if ( tfxApi ) |
|
5502 { |
|
5503 tfxApi->EnableEffects( EFalse ); |
|
5504 } |
|
5505 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
5506 } |
|
5507 |
|
5508 if ( iExtension->iPanningActive ) |
|
5509 { |
|
5510 TPoint delta( |
|
5511 0, iExtension->iPrevPoint.iY - aPointerEvent.iPosition.iY ); |
|
5512 iExtension->iPhysics->RegisterPanningPosition( delta ); |
|
5513 } |
|
5514 iExtension->iPrevPoint = aPointerEvent.iPosition; |
|
5515 |
|
5516 // in submenu and pointer dragged outside of x -limits : handle in parent |
|
5517 if ( iOwner && ((aPointerEvent.iPosition.iX < innerRect.iTl.iX ) || |
|
5518 ( aPointerEvent.iPosition.iX > innerRect.iBr.iX ))) |
|
5519 { |
|
5520 iExtension->CalculateParentEvent(aPointerEvent, parentEvent); |
|
5521 iExtension->iButtonDownItem = KErrNotFound; |
|
5522 iExtension->ResetPressedHighlight(); |
|
5523 } |
|
5524 |
|
5525 // act in Menu Sct or Option Menu repectively |
|
5526 if (( iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition)) || |
|
5527 ( !iExtension->iSct && innerRect.Contains(aPointerEvent.iPosition))) |
|
5528 { |
|
5529 iExtension->iDraggedOutside = EFalse; |
|
5530 // Scroll only through visible items |
|
5531 for ( TInt ii = topItem; ii < bottomItem; ++ii ) |
|
5532 { |
|
5533 CEikMenuPaneItem* item = (*iItemArray)[ii]; |
|
5534 |
|
5535 // if item is searched item. |
|
5536 if ( (yPos < item->iPos + iItemHeight) && (yPos |
|
5537 > item->iPos) ) |
|
5538 { |
|
5539 if ( iCascadeMenuPane ) |
|
5540 { |
|
5541 // if submenu open and touched item is not the one which opened submenu, then close submenu |
|
5542 if ( (ii != iSelectedItem) |
|
5543 && !cascadeMenuRect.Contains( |
|
5544 aPointerEvent.iPosition ) ) |
|
5545 { |
|
5546 if ( AknLayoutUtils::PenEnabled() ) |
|
5547 { |
|
5548 if ( CAknTransitionUtils::TransitionsEnabled( |
|
5549 AknTransEffect::EComponentTransitionsOff ) ) |
|
5550 { |
|
5551 iExtension->ImmediateFeedback( |
|
5552 ETouchFeedbackDecreasingPopUp ); |
|
5553 } |
|
5554 else |
|
5555 { |
|
5556 iExtension->ImmediateFeedback( |
|
5557 ETouchFeedbackPopUp ); |
|
5558 } |
|
5559 } |
|
5560 iExtension->iShowCascadeTransition = ETrue; |
|
5561 CloseCascadeMenu(); |
|
5562 } |
|
5563 } |
|
5564 else |
|
5565 { |
|
5566 TInt oldSelected = iSelectedItem; |
|
5567 // update highlight to new item |
|
5568 if ( oldSelected != ii ) |
|
5569 { |
|
5570 iExtension->iPressedDown = EFalse; |
|
5571 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5572 if ( effects |
|
5573 && !iExtension->iShowCascadeTransition ) |
|
5574 { |
|
5575 transApi->SetMoveType( |
|
5576 MAknListBoxTfxInternal::EListDrag ); |
|
5577 } |
|
5578 #endif |
|
5579 } |
|
5580 TRect screenRect( TPoint( KMinTInt, KMinTInt ), |
|
5581 TPoint( KMaxTInt, KMaxTInt ) ); |
|
5582 TRect repeatRect( screenRect.iTl.iX, item->iPos, |
|
5583 screenRect.iBr.iX, item->iPos |
|
5584 + iItemHeight ); |
|
5585 } |
|
5586 // item found, break |
|
5587 break; |
|
5588 } |
|
5589 } |
|
5590 |
|
5591 } |
|
5592 } |
|
5593 break; |
|
5594 |
|
5595 default: |
|
5596 break; |
|
5597 } |
|
5598 _AKNTRACE( "[%s]", "HandlePointerEventL return 16" ); |
|
5599 _AKNTRACE_FUNC_EXIT; |
|
5600 } |
|
5601 |
|
5602 // ----------------------------------------------------------------------------- |
|
5603 // CEikMenuPane::InputCapabilities |
|
5604 // Returns the input capabilites of the menu pane which accepts all text. |
|
5605 // |
|
5606 // @since ER5U |
|
5607 // ----------------------------------------------------------------------------- |
|
5608 // |
|
5609 EXPORT_C TCoeInputCapabilities CEikMenuPane::InputCapabilities() const |
|
5610 { |
|
5611 return TCoeInputCapabilities( TCoeInputCapabilities::EAllText ); // Max length parameter removed for release15 |
|
5612 } |
|
5613 |
|
5614 |
|
5615 // ----------------------------------------------------------------------------- |
|
5616 // CEikMenuPane::AddMenuItemL |
|
5617 // Adds a new menu item to the menu pane by creating a new menu item, setting its data to aMenuItem |
|
5618 // and appending it to the pane's menu item array. Updates the menu's scroll bar to take acount of the |
|
5619 // new item. |
|
5620 // SData is a structure so all fields in it should be set to avoid any unexpected behaviour. |
|
5621 // ----------------------------------------------------------------------------- |
|
5622 // |
|
5623 EXPORT_C void CEikMenuPane::AddMenuItemL( const CEikMenuPaneItem::SData& aMenuItem ) |
|
5624 // For use by Menu extensions |
|
5625 { |
|
5626 if ( !iItemArray ) |
|
5627 CreateItemArrayL(); |
|
5628 CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem(); |
|
5629 item->iData = aMenuItem; |
|
5630 iItemArray->AddItemL( item ); |
|
5631 UpdateScrollBar(); |
|
5632 } |
|
5633 |
|
5634 // ----------------------------------------------------------------------------- |
|
5635 // CEikMenuPane::AddMenuItemL |
|
5636 // ----------------------------------------------------------------------------- |
|
5637 // |
|
5638 EXPORT_C void CEikMenuPane::AddMenuItemL(const CEikMenuPaneItem::SData& aMenuItem, TInt aPreviousId) |
|
5639 { |
|
5640 if ( !iItemArray ) |
|
5641 CreateItemArrayL(); |
|
5642 CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem(); |
|
5643 item->iData=aMenuItem; |
|
5644 TInt position = 0; |
|
5645 ItemAndPos( aPreviousId, position ); |
|
5646 iItemArray->InsertL( position + 1, item); |
|
5647 UpdateScrollBar(); |
|
5648 } |
|
5649 |
|
5650 |
|
5651 |
|
5652 // ----------------------------------------------------------------------------- |
|
5653 // CEikMenuPane::DeleteMenuItem |
|
5654 // Deletes the menu item identified by aCommandId from the pane's item array. |
|
5655 // Updates the menu's scroll bar to take acount of the change. |
|
5656 // ----------------------------------------------------------------------------- |
|
5657 // |
|
5658 EXPORT_C void CEikMenuPane::DeleteMenuItem( TInt aCommandId ) |
|
5659 { |
|
5660 TInt count=0; |
|
5661 if( iItemArray ) |
|
5662 count=iItemArray->Count(); |
|
5663 for ( TInt ii = 0; ii < count; ++ii ) |
|
5664 { |
|
5665 CEikMenuPaneItem* item=(*iItemArray)[ii]; |
|
5666 if ( item->iData.iCommandId == aCommandId ) |
|
5667 { |
|
5668 iItemArray->Delete( ii ); |
|
5669 delete item; |
|
5670 UpdateScrollBar(); |
|
5671 return; |
|
5672 } |
|
5673 } |
|
5674 Panic( EEikPanicNoSuchMenuItem ); |
|
5675 } |
|
5676 |
|
5677 // ----------------------------------------------------------------------------- |
|
5678 // CEikMenuPane::DeleteBetweenMenuItems |
|
5679 // ----------------------------------------------------------------------------- |
|
5680 // |
|
5681 EXPORT_C void CEikMenuPane::DeleteBetweenMenuItems( TInt aStartIndex, TInt aEndIndex ) |
|
5682 { |
|
5683 __ASSERT_DEBUG( aStartIndex <= aEndIndex, Panic( EEikPanicNoSuchMenuItem ) ); |
|
5684 TInt items(0); |
|
5685 if( iItemArray ) |
|
5686 items=iItemArray->Count(); |
|
5687 if ( aEndIndex >= items ) |
|
5688 Panic( EEikPanicNoSuchMenuItem ); |
|
5689 |
|
5690 TInt count = aEndIndex - aStartIndex + 1; |
|
5691 for ( TInt ii = 0; ii < count; ii++ ) |
|
5692 { |
|
5693 CEikMenuPaneItem* item = (*iItemArray)[aStartIndex]; |
|
5694 iItemArray->Delete( aStartIndex ); |
|
5695 delete item; |
|
5696 } |
|
5697 UpdateScrollBar(); |
|
5698 } |
|
5699 |
|
5700 |
|
5701 |
|
5702 // ----------------------------------------------------------------------------- |
|
5703 // CEikMenuPane::ItemData |
|
5704 // Returns a reference to the data in the menu item identified by aCommandId. |
|
5705 // ----------------------------------------------------------------------------- |
|
5706 // |
|
5707 EXPORT_C CEikMenuPaneItem::SData& CEikMenuPane::ItemData( TInt aCommandId ) |
|
5708 { |
|
5709 TInt pos; |
|
5710 CEikMenuPaneItem* item=ItemAndPos( aCommandId, pos ); |
|
5711 return item->iData; |
|
5712 } |
|
5713 |
|
5714 |
|
5715 // ----------------------------------------------------------------------------- |
|
5716 // CEikMenuPane::ItemAndPos |
|
5717 // Returns a pointer to the menu item identified by aCommandId and gets the position of the item in aPos. |
|
5718 // ----------------------------------------------------------------------------- |
|
5719 // |
|
5720 EXPORT_C CEikMenuPaneItem* CEikMenuPane::ItemAndPos( TInt aCommandId, TInt& aPos ) |
|
5721 { |
|
5722 TInt count(0); |
|
5723 if( iItemArray ) |
|
5724 count = iItemArray->Count(); |
|
5725 aPos = 0; |
|
5726 CEikMenuPaneItem* item; |
|
5727 FOREVER |
|
5728 { |
|
5729 if ( aPos == count ) |
|
5730 Panic( EEikPanicNoSuchMenuItem ); |
|
5731 item = (*iItemArray)[aPos]; |
|
5732 if ( item->iData.iCommandId == aCommandId ) |
|
5733 break; |
|
5734 ++aPos; |
|
5735 } |
|
5736 return item; |
|
5737 } |
|
5738 |
|
5739 // ----------------------------------------------------------------------------- |
|
5740 // CEikMenuPane::SetItemTextL |
|
5741 // Sets the text of the menu item identified by aCommandId by reading it from the resource with id aRid. |
|
5742 // ----------------------------------------------------------------------------- |
|
5743 // |
|
5744 EXPORT_C void CEikMenuPane::SetItemTextL(TInt aCommandId,TInt aRid) |
|
5745 { |
|
5746 TBuf<80> tmp; |
|
5747 iCoeEnv->ReadResource( tmp, aRid ); |
|
5748 SetItemTextL( aCommandId, tmp); |
|
5749 } |
|
5750 |
|
5751 |
|
5752 // ----------------------------------------------------------------------------- |
|
5753 // CEikMenuPane::SetItemTextL |
|
5754 // Sets the text of the menu item identified by aCommandId to the descriptor aDes. |
|
5755 // ----------------------------------------------------------------------------- |
|
5756 // |
|
5757 EXPORT_C void CEikMenuPane::SetItemTextL( TInt aCommandId, const TDesC& aDes ) |
|
5758 { |
|
5759 TInt pos; |
|
5760 CEikMenuPaneItem* newItem=ItemAndPos( aCommandId, pos ); |
|
5761 newItem->iData.iText.Copy( aDes ); |
|
5762 } |
|
5763 |
|
5764 // ----------------------------------------------------------------------------- |
|
5765 // CEikMenuPane::SetItemDimmed |
|
5766 // ----------------------------------------------------------------------------- |
|
5767 // |
|
5768 EXPORT_C void CEikMenuPane::SetItemDimmed( TInt aCommandId, TBool aDimmed ) |
|
5769 { |
|
5770 CEikMenuPaneItem::SData& itemData = ItemData(aCommandId); |
|
5771 if ( aDimmed ) |
|
5772 itemData.iFlags |= EEikMenuItemDimmed; |
|
5773 else |
|
5774 itemData.iFlags &= ( ~EEikMenuItemDimmed ); |
|
5775 } |
|
5776 |
|
5777 |
|
5778 // ----------------------------------------------------------------------------- |
|
5779 // CEikMenuPane::SetItemButtonState |
|
5780 // Sets the item to be indicated or not. It should be used to change the state of radio |
|
5781 // buttons or check box items. |
|
5782 // It has real effect only starting from v3.0. |
|
5783 // @param aButtonState should be EEikMenuItemSymbolOn or EEikMenuItemSymbolIndeterminate |
|
5784 // ----------------------------------------------------------------------------- |
|
5785 // |
|
5786 EXPORT_C void CEikMenuPane::SetItemButtonState( TInt aCommandId,TInt aButtonState ) |
|
5787 { |
|
5788 TInt pos(0); |
|
5789 CEikMenuPaneItem* item = ItemAndPos( aCommandId, pos ); |
|
5790 |
|
5791 if ( IsItemMemberOfRadioButtonGroup( pos ) ) |
|
5792 { |
|
5793 if( aButtonState&EEikMenuItemSymbolOn ) |
|
5794 { |
|
5795 iExtension->iSelectedRadioButtonItem = pos; |
|
5796 } |
|
5797 else if( iExtension->iSelectedRadioButtonItem == pos ) |
|
5798 { |
|
5799 iExtension->iSelectedRadioButtonItem = KNoSelectedRadioButtonItem; |
|
5800 } |
|
5801 } |
|
5802 |
|
5803 item->iData.iFlags&=( ~(EEikMenuItemSymbolOn|EEikMenuItemSymbolIndeterminate) ); // clears the flags |
|
5804 if ( aButtonState&EEikMenuItemSymbolOn ) |
|
5805 { |
|
5806 item->iData.iFlags |= EEikMenuItemSymbolOn; |
|
5807 } |
|
5808 else if ( aButtonState&EEikMenuItemSymbolIndeterminate ) |
|
5809 { |
|
5810 item->iData.iFlags |= EEikMenuItemSymbolIndeterminate; |
|
5811 } |
|
5812 } |
|
5813 |
|
5814 // ----------------------------------------------------------------------------- |
|
5815 // CEikMenuPane::SetSelectedItem |
|
5816 // ----------------------------------------------------------------------------- |
|
5817 // |
|
5818 EXPORT_C void CEikMenuPane::SetSelectedItem( TInt aSelectedItem ) |
|
5819 { |
|
5820 iSelectedItem = (aSelectedItem >= NumberOfItemsInPane() ) ? 0 : aSelectedItem; |
|
5821 |
|
5822 if( iExtension ) |
|
5823 iExtension->ChangeHighlightBackground(); |
|
5824 } |
|
5825 |
|
5826 // ----------------------------------------------------------------------------- |
|
5827 // CEikMenuPane::SelectedItem |
|
5828 // ----------------------------------------------------------------------------- |
|
5829 // |
|
5830 EXPORT_C TInt CEikMenuPane::SelectedItem() const |
|
5831 { |
|
5832 return iSelectedItem; |
|
5833 } |
|
5834 |
|
5835 // ----------------------------------------------------------------------------- |
|
5836 // CEikMenuPane::SetItemArray |
|
5837 // ----------------------------------------------------------------------------- |
|
5838 // |
|
5839 EXPORT_C void CEikMenuPane::SetItemArray( CItemArray* aItemArray ) |
|
5840 { |
|
5841 if ( !ItemArrayOwnedExternally() ) |
|
5842 delete iItemArray; |
|
5843 iItemArray = aItemArray; |
|
5844 } |
|
5845 |
|
5846 // ----------------------------------------------------------------------------- |
|
5847 // CEikMenuPane::SetItemArrayOwnedExternally |
|
5848 // ----------------------------------------------------------------------------- |
|
5849 // |
|
5850 EXPORT_C void CEikMenuPane::SetItemArrayOwnedExternally( TBool aOwnedExternally ) |
|
5851 { |
|
5852 iArrayOwnedExternally=aOwnedExternally; |
|
5853 } |
|
5854 |
|
5855 // ----------------------------------------------------------------------------- |
|
5856 // CEikMenuPane::SetLaunchingButton |
|
5857 // ----------------------------------------------------------------------------- |
|
5858 // |
|
5859 EXPORT_C void CEikMenuPane::SetLaunchingButton( CEikButtonBase* aButton ) |
|
5860 { |
|
5861 iLaunchingButton = aButton; |
|
5862 } |
|
5863 |
|
5864 |
|
5865 // ----------------------------------------------------------------------------- |
|
5866 // CEikMenuPane::NumberOfItemsInPane |
|
5867 // Returns the number of menu items. |
|
5868 // ----------------------------------------------------------------------------- |
|
5869 // |
|
5870 EXPORT_C TInt CEikMenuPane::NumberOfItemsInPane() const |
|
5871 { |
|
5872 return( iItemArray ? iItemArray->Count() : 0); |
|
5873 } |
|
5874 |
|
5875 // ----------------------------------------------------------------------------- |
|
5876 // CEikMenuPane::Close |
|
5877 // ----------------------------------------------------------------------------- |
|
5878 // |
|
5879 EXPORT_C void CEikMenuPane::Close() |
|
5880 { |
|
5881 if( iExtension ) |
|
5882 { |
|
5883 iExtension->iPressedDown = EFalse; |
|
5884 iExtension->ResetPressedHighlight(); |
|
5885 } |
|
5886 |
|
5887 if ( OwnsWindow() ) |
|
5888 CloseWindow(); |
|
5889 |
|
5890 if( iExtension ) |
|
5891 iExtension->MenuClosed(); |
|
5892 } |
|
5893 |
|
5894 // ----------------------------------------------------------------------------- |
|
5895 // CEikMenuPane::Reserved_1 |
|
5896 // ----------------------------------------------------------------------------- |
|
5897 // |
|
5898 EXPORT_C void CEikMenuPane::Reserved_1() |
|
5899 {} |
|
5900 |
|
5901 // ----------------------------------------------------------------------------- |
|
5902 // CEikMenuPane::Reserved_2 |
|
5903 // ----------------------------------------------------------------------------- |
|
5904 // |
|
5905 EXPORT_C void CEikMenuPane::Reserved_2() |
|
5906 {} |
|
5907 |
|
5908 |
|
5909 //---------------------------------------------------------------------------- |
|
5910 // CEikMenuPane::HandleScrollEventL() |
|
5911 // |
|
5912 // Handles scroll events by calculating new top and botton item indexes |
|
5913 // and then drawing all items that fit to screen |
|
5914 //---------------------------------------------------------------------------- |
|
5915 // |
|
5916 void CEikMenuPane::HandleScrollEventL( CEikScrollBar* aScrollBar, TEikScrollEvent aEventType ) |
|
5917 { |
|
5918 _AKNTRACE_FUNC_ENTER; |
|
5919 if( !AknLayoutUtils::PenEnabled()) |
|
5920 { |
|
5921 return; |
|
5922 } |
|
5923 |
|
5924 _AKNTRACE( "[%s]", "Stop physics engine"); |
|
5925 iExtension->iPhysics->StopPhysics(); |
|
5926 iExtension->iPhysics->ResetFriction(); |
|
5927 |
|
5928 // flag for do we need to update or even calculate scrolling |
|
5929 TBool update = ETrue; |
|
5930 |
|
5931 // if submenu is opened, close it because scrolling in submenu is not possible. |
|
5932 // and in this case it also means tapping outside of submenu. |
|
5933 if (iCascadeMenuPane) |
|
5934 { |
|
5935 _AKNTRACE( "[%s]", "CloseCascadeMenu"); |
|
5936 CloseCascadeMenu(); |
|
5937 update = EFalse; |
|
5938 } |
|
5939 |
|
5940 // how many items fit to view |
|
5941 const TInt itemsThatFitToView = NumberOfItemsThatFitInView(); |
|
5942 |
|
5943 // How many items there are in this menu. |
|
5944 TInt countOfItems = 0; |
|
5945 if( iItemArray ) |
|
5946 { |
|
5947 countOfItems = iItemArray->Count(); |
|
5948 } |
|
5949 |
|
5950 // if scrolling is impossible because (there is not enough items to be scrolled) |
|
5951 if ( countOfItems < itemsThatFitToView ) |
|
5952 { |
|
5953 update = EFalse; |
|
5954 } |
|
5955 |
|
5956 // Get top and botton item indexes. |
|
5957 TInt topItem = iScroller->TopItemIndex(); |
|
5958 TInt bottomItem = topItem + itemsThatFitToView; |
|
5959 _AKNTRACE( "topItem = %d", topItem); |
|
5960 _AKNTRACE( "bottomItem = %d", bottomItem); |
|
5961 |
|
5962 if( bottomItem > NumberOfItemsInPane() ) |
|
5963 { |
|
5964 bottomItem = NumberOfItemsInPane(); |
|
5965 } |
|
5966 |
|
5967 // Items that becomes topmost and downmost items |
|
5968 TInt newTopItem = 0; |
|
5969 |
|
5970 |
|
5971 // if update is not wanted, do nothing. |
|
5972 if ( update ) |
|
5973 { |
|
5974 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5975 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( |
|
5976 iExtension->iGc ); |
|
5977 TBool effects = transApi && !transApi->EffectsDisabled(); |
|
5978 #endif |
|
5979 |
|
5980 switch (aEventType) |
|
5981 { |
|
5982 case EEikScrollUp: |
|
5983 { |
|
5984 _AKNTRACE( "[%s]", "EEikScrollUp"); |
|
5985 _AKNTRACE( "topItem = %d", topItem); |
|
5986 // if topItem is not upmost |
|
5987 if ( topItem > 0) |
|
5988 { |
|
5989 // move menu to one step up. |
|
5990 newTopItem = topItem - 1; |
|
5991 } |
|
5992 else |
|
5993 { |
|
5994 newTopItem = countOfItems - itemsThatFitToView; |
|
5995 } |
|
5996 _AKNTRACE( "newTopItem = %d", newTopItem); |
|
5997 } |
|
5998 break; |
|
5999 |
|
6000 case EEikScrollDown: |
|
6001 { |
|
6002 _AKNTRACE( "[%s]", "EEikScrollDown"); |
|
6003 _AKNTRACE( "bottomItem = %d", bottomItem); |
|
6004 // if last item is not visible |
|
6005 if ( bottomItem < countOfItems) |
|
6006 { |
|
6007 // move menu to show one step down. |
|
6008 newTopItem = topItem + 1; |
|
6009 } |
|
6010 else |
|
6011 { |
|
6012 newTopItem = 0; |
|
6013 } |
|
6014 _AKNTRACE( "newTopItem = %d", newTopItem); |
|
6015 } |
|
6016 break; |
|
6017 |
|
6018 case EEikScrollPageUp: |
|
6019 { |
|
6020 _AKNTRACE( "[%s]", "EEikScrollPageUp"); |
|
6021 _AKNTRACE( "topItem = %d", topItem); |
|
6022 // if topItem is not upmost |
|
6023 if ( topItem > 0) |
|
6024 { |
|
6025 // move menu to show one site up or then upmost. |
|
6026 newTopItem = (topItem > itemsThatFitToView) ? (topItem - itemsThatFitToView) : 0; |
|
6027 } |
|
6028 else |
|
6029 { |
|
6030 update = EFalse; |
|
6031 } |
|
6032 _AKNTRACE( "newTopItem = %d", newTopItem); |
|
6033 _AKNTRACE( "update = %d", update); |
|
6034 } |
|
6035 break; |
|
6036 |
|
6037 case EEikScrollPageDown: |
|
6038 { |
|
6039 _AKNTRACE( "[%s]", "EEikScrollPageDown"); |
|
6040 _AKNTRACE( "bottomItem = %d", bottomItem); |
|
6041 // if last item is not visible |
|
6042 if ( bottomItem < countOfItems) |
|
6043 { |
|
6044 // move menu to show one site down or then downmost items. |
|
6045 newTopItem = (bottomItem <= (countOfItems - itemsThatFitToView)) ? (topItem + itemsThatFitToView) : (countOfItems - itemsThatFitToView); |
|
6046 } |
|
6047 else |
|
6048 { |
|
6049 update = EFalse; |
|
6050 } |
|
6051 _AKNTRACE( "newTopItem = %d", newTopItem); |
|
6052 _AKNTRACE( "update = %d", update); |
|
6053 } |
|
6054 break; |
|
6055 |
|
6056 case EEikScrollThumbDragVert: |
|
6057 { |
|
6058 _AKNTRACE( "[%s]", "EEikScrollThumbDragVert"); |
|
6059 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6060 |
|
6061 if ( effects ) |
|
6062 { |
|
6063 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc ); |
|
6064 |
|
6065 if ( tfxApi ) |
|
6066 { |
|
6067 tfxApi->EnableEffects( EFalse ); |
|
6068 effects = EFalse; |
|
6069 } |
|
6070 } |
|
6071 #endif |
|
6072 // new thumb position |
|
6073 TInt thumb = aScrollBar->ThumbPosition(); |
|
6074 _AKNTRACE( "thumb = %d", thumb); |
|
6075 |
|
6076 // did dragging cause scrolling |
|
6077 if ( thumb != topItem ) |
|
6078 { |
|
6079 newTopItem = thumb; |
|
6080 } |
|
6081 else |
|
6082 { |
|
6083 update = EFalse; |
|
6084 } |
|
6085 _AKNTRACE( "newTopItem = %d", newTopItem); |
|
6086 _AKNTRACE( "update = %d", update); |
|
6087 } |
|
6088 break; |
|
6089 |
|
6090 case EEikScrollThumbReleaseVert: |
|
6091 { |
|
6092 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6093 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc ); |
|
6094 |
|
6095 if ( tfxApi ) |
|
6096 { |
|
6097 tfxApi->EnableEffects( ETrue ); |
|
6098 } |
|
6099 #endif |
|
6100 } |
|
6101 return; |
|
6102 |
|
6103 default: |
|
6104 update = EFalse; |
|
6105 break; |
|
6106 } |
|
6107 |
|
6108 |
|
6109 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6110 if ( effects ) |
|
6111 { |
|
6112 transApi->SetMoveType( newTopItem > topItem ? |
|
6113 MAknListBoxTfxInternal::EListScrollDown : |
|
6114 MAknListBoxTfxInternal::EListScrollUp ); |
|
6115 } |
|
6116 #endif |
|
6117 |
|
6118 |
|
6119 iExtension->iListTopIndex = aScrollBar->ThumbPosition(); |
|
6120 |
|
6121 iExtension->iViewPosition.iY = |
|
6122 iExtension->iListTopIndex + iExtension->iViewHeight / 2; |
|
6123 |
|
6124 iExtension->ViewPositionChanged( iExtension->iViewPosition ); |
|
6125 |
|
6126 } |
|
6127 _AKNTRACE_FUNC_EXIT; |
|
6128 } |
|
6129 |
|
6130 // ----------------------------------------------------------------------------- |
|
6131 // CEikMenuPane::CreateScrollBarFrame |
|
6132 // ----------------------------------------------------------------------------- |
|
6133 // |
|
6134 void CEikMenuPane::CreateScrollBarFrame() |
|
6135 { |
|
6136 if (!CheckCreateScroller()) |
|
6137 return; |
|
6138 TRAPD( err,( iSBFrame = new(ELeave) CEikScrollBarFrame( this, iScroller, ETrue, ETrue ) ) ); |
|
6139 if ( !err ) |
|
6140 { |
|
6141 CEikScrollBarFrame::TScrollBarVisibility visibility = CEikScrollBarFrame::EOn; |
|
6142 |
|
6143 if ( iOwner && ( iItemArray->Count() <= NumberOfItemsThatFitInView() ) ) |
|
6144 { |
|
6145 // submenu with less than 6 items |
|
6146 visibility = CEikScrollBarFrame::EOff; |
|
6147 } |
|
6148 TRAP_IGNORE( iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, visibility /*CEikScrollBarFrame::EAuto*/ ) ); |
|
6149 |
|
6150 TRAP_IGNORE( iSBFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse, ETrue, EFalse ) ); |
|
6151 iSBFrame->DrawBackground( EFalse, EFalse ); |
|
6152 UpdateScrollBar(); |
|
6153 } |
|
6154 } |
|
6155 |
|
6156 |
|
6157 // ----------------------------------------------------------------------------- |
|
6158 // CEikMenuPane::UpdateScrollBar |
|
6159 // ----------------------------------------------------------------------------- |
|
6160 // |
|
6161 void CEikMenuPane::UpdateScrollBar() |
|
6162 { |
|
6163 if ( !CheckCreateScroller() ) |
|
6164 return; |
|
6165 CIdle* idle = iScroller->Idle(); |
|
6166 if ( idle && !idle->IsActive() ) |
|
6167 idle->Start( TCallBack( CEikMenuPane::UpdateScrollBarCallBackL, this ) ); |
|
6168 } |
|
6169 |
|
6170 // ----------------------------------------------------------------------------- |
|
6171 // CEikMenuPane::UpdateScrollBarCallBackL |
|
6172 // ----------------------------------------------------------------------------- |
|
6173 // |
|
6174 TInt CEikMenuPane::UpdateScrollBarCallBackL( TAny* aObj ) |
|
6175 { // static |
|
6176 REINTERPRET_CAST(CEikMenuPane*,aObj)->DoUpdateScrollBarL(); |
|
6177 return 0; |
|
6178 } |
|
6179 |
|
6180 // ----------------------------------------------------------------------------- |
|
6181 // CEikMenuPane::DoUpdateScrollBarL |
|
6182 // ----------------------------------------------------------------------------- |
|
6183 // |
|
6184 void CEikMenuPane::DoUpdateScrollBarL() |
|
6185 { |
|
6186 if (!iSBFrame) |
|
6187 return; |
|
6188 _AKNTRACE_FUNC_ENTER; |
|
6189 TEikScrollBarModel hSbarModel; |
|
6190 TEikScrollBarModel vSbarModel; |
|
6191 |
|
6192 TRect menuPaneRect; |
|
6193 if ( !iOwner ) |
|
6194 { |
|
6195 menuPaneRect = iExtension->iMenuPaneRect; |
|
6196 } |
|
6197 else |
|
6198 { |
|
6199 menuPaneRect = Rect(); |
|
6200 } |
|
6201 |
|
6202 TRect clientRect( menuPaneRect.Size() ); |
|
6203 |
|
6204 // Panning uses pixel resolution scrollbar |
|
6205 vSbarModel.iThumbPosition = iExtension->iListTopIndex; |
|
6206 vSbarModel.iScrollSpan = TotalItemHeight(); |
|
6207 vSbarModel.iThumbSpan = iExtension->iViewHeight; |
|
6208 |
|
6209 // Double span scroll bar uses different model, just convert to it here. |
|
6210 TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel ); |
|
6211 TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel ); |
|
6212 |
|
6213 TRect scrollBarInclusiveRect( clientRect ); |
|
6214 TRect scrollBarClientRect( scrollBarInclusiveRect ); |
|
6215 |
|
6216 TEikScrollBarFrameLayout layout; |
|
6217 layout.SetClientMargin( 0 ); |
|
6218 layout.SetInclusiveMargin( 0 ); |
|
6219 layout.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant; |
|
6220 |
|
6221 // For main menupane scrollbar is always shown, for submenu only when needed |
|
6222 if ( !iOwner ) |
|
6223 { |
|
6224 iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn ); |
|
6225 } |
|
6226 else |
|
6227 { |
|
6228 TInt maxItems = NumberOfItemsThatFitInView(); |
|
6229 TInt count = iItemArray->Count(); |
|
6230 iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, |
|
6231 (count > maxItems) ? CEikScrollBarFrame::EOn : CEikScrollBarFrame::EOff ); |
|
6232 } |
|
6233 |
|
6234 TAknLayoutRect scrollLayoutRect; |
|
6235 if ( !iOwner ) |
|
6236 { |
|
6237 TAknWindowLineLayout listScrollPaneLayout( |
|
6238 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
6239 if ( iExtension ) |
|
6240 { |
|
6241 iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); |
|
6242 } |
|
6243 scrollLayoutRect.LayoutRect( clientRect, listScrollPaneLayout ); |
|
6244 scrollBarInclusiveRect = scrollLayoutRect.Rect(); |
|
6245 scrollBarClientRect = scrollBarInclusiveRect; |
|
6246 |
|
6247 AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect, |
|
6248 AknLayoutScalable_Avkon::scroll_pane_cp25(0).LayoutLine() ); |
|
6249 } |
|
6250 else |
|
6251 { |
|
6252 scrollLayoutRect.LayoutRect( clientRect, |
|
6253 AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); |
|
6254 scrollBarInclusiveRect = scrollLayoutRect.Rect(); |
|
6255 scrollBarClientRect = scrollBarInclusiveRect; |
|
6256 |
|
6257 AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect, |
|
6258 AknLayoutScalable_Avkon::scroll_pane_cp4().LayoutLine()); |
|
6259 } |
|
6260 |
|
6261 iSBFrame->TileL( &hDsSbarModel, &vDsSbarModel, scrollBarClientRect, scrollBarInclusiveRect, layout ); |
|
6262 iSBFrame->SetVFocusPosToThumbPos( vDsSbarModel.FocusPosition() ); |
|
6263 |
|
6264 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6265 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
6266 if ( iSBFrame->VerticalScrollBar() && |
|
6267 iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn ) |
|
6268 { |
|
6269 iExtension->iScrollBarRect = iSBFrame->VerticalScrollBar()->Rect(); |
|
6270 } |
|
6271 else |
|
6272 { |
|
6273 iExtension->iScrollBarRect = TRect::EUninitialized; |
|
6274 } |
|
6275 if ( transApi ) |
|
6276 { |
|
6277 transApi->ResetNonDrawingRects(); |
|
6278 transApi->AddNonDrawingRect( iExtension->iScrollBarRect ); |
|
6279 transApi->AddNonDrawingRect( iExtension->iSctRect ); |
|
6280 } |
|
6281 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
6282 if ( iSBFrame->VerticalScrollBar() && |
|
6283 iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn ) |
|
6284 { |
|
6285 iExtension->iSBRect = iSBFrame->VerticalScrollBar()->Rect(); |
|
6286 } |
|
6287 else |
|
6288 { |
|
6289 iExtension->iSBRect = TRect::EUninitialized; |
|
6290 } |
|
6291 _AKNTRACE_FUNC_EXIT; |
|
6292 } |
|
6293 |
|
6294 // ----------------------------------------------------------------------------- |
|
6295 // CEikMenuPane::UpdateScrollBarThumbs |
|
6296 // ----------------------------------------------------------------------------- |
|
6297 // |
|
6298 void CEikMenuPane::UpdateScrollBarThumbs() |
|
6299 { |
|
6300 if ( iSBFrame ) |
|
6301 { |
|
6302 iSBFrame->SetVFocusPosToThumbPos( iExtension->iListTopIndex ); |
|
6303 } |
|
6304 } |
|
6305 |
|
6306 // ----------------------------------------------------------------------------- |
|
6307 // CEikMenuPane::ScrollToMakeItemVisible |
|
6308 // ----------------------------------------------------------------------------- |
|
6309 // |
|
6310 void CEikMenuPane::ScrollToMakeItemVisible(TInt aItemIndex) |
|
6311 { |
|
6312 _AKNTRACE_FUNC_ENTER; |
|
6313 if( !iItemArray || iItemArray->Count() == 0 ) |
|
6314 return; |
|
6315 if ( !CheckCreateScroller() ) |
|
6316 return; |
|
6317 |
|
6318 if(iExtension->iSctHighlighted && aItemIndex == ENothingSelected) |
|
6319 aItemIndex = 0; |
|
6320 else if(aItemIndex == ENothingSelected) |
|
6321 return; |
|
6322 |
|
6323 TInt maxItems = NumberOfItemsThatFitInView(); |
|
6324 |
|
6325 if ( iExtension->Offset() < 0 ) |
|
6326 { |
|
6327 maxItems++; |
|
6328 } |
|
6329 // |
|
6330 // S60 menus are fixed size pitch and known size so scrolling can be based on index |
|
6331 // |
|
6332 TInt amountToScroll = 0; |
|
6333 if ( aItemIndex < iScroller->TopItemIndex() ) |
|
6334 { // +ve scroll |
|
6335 amountToScroll = iItemHeight * ( iScroller->TopItemIndex() - aItemIndex ); |
|
6336 } |
|
6337 else if ( aItemIndex >= ( iScroller->TopItemIndex() + maxItems ) ) |
|
6338 { |
|
6339 amountToScroll = iItemHeight * ( ( iScroller->TopItemIndex() + |
|
6340 maxItems ) - aItemIndex - 1 ); |
|
6341 } |
|
6342 if ( amountToScroll ) |
|
6343 { |
|
6344 _AKNTRACE( "amountToScroll = %d", amountToScroll ); |
|
6345 Scroll(amountToScroll); |
|
6346 |
|
6347 if ( !iExtension->isUpdateScrollDirectly ) |
|
6348 { |
|
6349 UpdateScrollBar(); |
|
6350 } |
|
6351 else |
|
6352 { |
|
6353 DoUpdateScrollBarL(); |
|
6354 } |
|
6355 } |
|
6356 _AKNTRACE_FUNC_EXIT; |
|
6357 return; |
|
6358 } |
|
6359 |
|
6360 // ----------------------------------------------------------------------------- |
|
6361 // CEikMenuPane::Scroll |
|
6362 // ----------------------------------------------------------------------------- |
|
6363 // |
|
6364 void CEikMenuPane::Scroll( TInt aAmount ) |
|
6365 { |
|
6366 _AKNTRACE_FUNC_ENTER; |
|
6367 if ( !CheckCreateScroller() ) |
|
6368 return; |
|
6369 TInt count=0; |
|
6370 if( iItemArray ) |
|
6371 count = iItemArray->Count(); |
|
6372 |
|
6373 // convert aAmount to a multiple of iItemHeight. |
|
6374 TInt integer = aAmount / iItemHeight; |
|
6375 TReal real = TReal( TReal( aAmount ) / TReal( iItemHeight ) ); |
|
6376 if ( real > TReal( integer ) ) // make more positive |
|
6377 aAmount = ( integer + 1 ) * iItemHeight; |
|
6378 if ( real < TReal( integer ) ) // make more negative |
|
6379 aAmount = ( integer - 1 ) * iItemHeight; |
|
6380 |
|
6381 // convert amount back into indices for S60 |
|
6382 TInt newTop = iScroller->TopItemIndex() - ( aAmount / iItemHeight ); // don't think there should be a divide by 0 here. |
|
6383 newTop = Max( 0, newTop ); |
|
6384 newTop = Min( newTop, count - NumberOfItemsThatFitInView() ); |
|
6385 iScroller->SetTopItemIndex( newTop ); |
|
6386 _AKNTRACE( "newTop = %d", newTop ); |
|
6387 |
|
6388 // Menu moved with keys, update panning/flicking data |
|
6389 iExtension->iListTopIndex = iScroller->TopItemIndex() * iItemHeight; |
|
6390 iExtension->iViewPosition.iY = |
|
6391 iExtension->iListTopIndex + iExtension->iViewHeight / 2; |
|
6392 |
|
6393 iExtension->SetOffset( 0 ); |
|
6394 |
|
6395 _AKNTRACE( "iExtension->iListTopIndex = %d", iExtension->iListTopIndex ); |
|
6396 _AKNTRACE( "iExtension->iViewPosition.iY = %d", iExtension->iViewPosition.iY ); |
|
6397 _AKNTRACE( "[%s]", "iExtension->SetOffset( 0 )" ); |
|
6398 |
|
6399 _AKNTRACE_FUNC_EXIT; |
|
6400 return; |
|
6401 } |
|
6402 |
|
6403 // ----------------------------------------------------------------------------- |
|
6404 // CEikMenuPane::ViewRect |
|
6405 // ----------------------------------------------------------------------------- |
|
6406 // |
|
6407 TRect CEikMenuPane::ViewRect() const |
|
6408 { |
|
6409 return Rect(); |
|
6410 } |
|
6411 |
|
6412 // ----------------------------------------------------------------------------- |
|
6413 // CEikMenuPane::NumberOfItemsThatFitInView |
|
6414 // ----------------------------------------------------------------------------- |
|
6415 // |
|
6416 TInt CEikMenuPane::NumberOfItemsThatFitInView() const |
|
6417 { |
|
6418 TInt subst = 0; |
|
6419 if ( iExtension->iSct ) |
|
6420 { |
|
6421 subst = 1; |
|
6422 } |
|
6423 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6424 iExtension->iItemsThatFitInView = iOwner ? AknLayoutScalable_Avkon:: |
|
6425 list_single_popup_submenu_pane_ParamLimits().LastRow() + 1 : |
|
6426 AknLayoutScalable_Avkon:: |
|
6427 list_single_pane_cp2_ParamLimits().LastRow() + 1 - subst; |
|
6428 if ( Layout_Meta_Data::IsLandscapeOrientation() |
|
6429 && iExtension->iItemsThatFitInView == 6 ) |
|
6430 { |
|
6431 iExtension->iItemsThatFitInView --; |
|
6432 } |
|
6433 |
|
6434 if ( iExtension->iPhysics && iExtension->Offset() != 0 ) |
|
6435 { |
|
6436 // with kinetic scrolling there can be partial items on the screen |
|
6437 iExtension->iTotalNumberOfItemsInView = iExtension->iItemsThatFitInView + 1; |
|
6438 } |
|
6439 |
|
6440 return iExtension->iItemsThatFitInView; |
|
6441 #else |
|
6442 return iOwner ? AknLayoutScalable_Avkon:: |
|
6443 list_single_popup_submenu_pane_ParamLimits().LastRow() + 1 : |
|
6444 AknLayoutScalable_Avkon:: |
|
6445 list_single_pane_cp2_ParamLimits().LastRow() + 1 - subst; |
|
6446 #endif |
|
6447 } |
|
6448 |
|
6449 // ----------------------------------------------------------------------------- |
|
6450 // CEikMenuPane::TotalItemHeight |
|
6451 // ----------------------------------------------------------------------------- |
|
6452 // |
|
6453 TInt CEikMenuPane::TotalItemHeight() const |
|
6454 { |
|
6455 TInt height(0); |
|
6456 TInt count(0); |
|
6457 if( iItemArray ) |
|
6458 count = iItemArray->Count(); |
|
6459 for (TInt ii = 0; ii < count; ++ii ) |
|
6460 { |
|
6461 height += iItemHeight; |
|
6462 } |
|
6463 |
|
6464 if ( iExtension->iSct ) |
|
6465 { |
|
6466 height += iItemHeight; |
|
6467 } |
|
6468 return height; |
|
6469 } |
|
6470 |
|
6471 |
|
6472 // ----------------------------------------------------------------------------- |
|
6473 // CEikMenuPane::CheckCreateScroller |
|
6474 // ----------------------------------------------------------------------------- |
|
6475 // |
|
6476 TBool CEikMenuPane::CheckCreateScroller() |
|
6477 { |
|
6478 TInt err = KErrNone; |
|
6479 if ( !iScroller ) |
|
6480 { |
|
6481 TRAP( err,( iScroller = CMenuScroller::NewL( *this ) ) ); |
|
6482 } |
|
6483 return err == KErrNone; |
|
6484 } |
|
6485 |
|
6486 // ----------------------------------------------------------------------------- |
|
6487 // CEikMenuPane::CheckCreateScrollerL |
|
6488 // ----------------------------------------------------------------------------- |
|
6489 // |
|
6490 void CEikMenuPane::CheckCreateScrollerL() |
|
6491 { |
|
6492 if ( !iScroller ) |
|
6493 iScroller = CMenuScroller::NewL( *this ); |
|
6494 } |
|
6495 |
|
6496 |
|
6497 // ----------------------------------------------------------------------------- |
|
6498 // CEikMenuPane::ItemArrayOwnedExternally |
|
6499 // ----------------------------------------------------------------------------- |
|
6500 // |
|
6501 TBool CEikMenuPane::ItemArrayOwnedExternally() const |
|
6502 { |
|
6503 return iArrayOwnedExternally; |
|
6504 } |
|
6505 |
|
6506 |
|
6507 // ----------------------------------------------------------------------------- |
|
6508 // CEikMenuPane::GetColorUseListL |
|
6509 // Gets the list of logical colors employed in the drawing of the control, |
|
6510 // paired with an explanation of how they are used. Appends the list into aColorUseList. |
|
6511 // |
|
6512 // @since ER5U |
|
6513 // ----------------------------------------------------------------------------- |
|
6514 // |
|
6515 EXPORT_C void CEikMenuPane::GetColorUseListL( CArrayFix<TCoeColorUse>& aColorUseList ) const |
|
6516 { |
|
6517 CEikBorderedControl::GetColorUseListL( aColorUseList ); |
|
6518 |
|
6519 TInt commonAttributes = TCoeColorUse::ENormal|TCoeColorUse::ENeutral; |
|
6520 TCoeColorUse colorUse; |
|
6521 |
|
6522 colorUse.SetLogicalColor( EColorMenuPaneText ); |
|
6523 colorUse.SetUse( TCoeColorUse::EFore|TCoeColorUse::EActive|TCoeColorUse::ESurrounds|commonAttributes ); |
|
6524 aColorUseList.AppendL( colorUse ); |
|
6525 |
|
6526 colorUse.SetLogicalColor( EColorMenuPaneBackground ); |
|
6527 colorUse.SetUse( TCoeColorUse::EBack|TCoeColorUse::EActive|TCoeColorUse::ESurrounds|commonAttributes); |
|
6528 aColorUseList.AppendL( colorUse ); |
|
6529 |
|
6530 colorUse.SetLogicalColor( EColorMenuPaneTextHighlight ); |
|
6531 colorUse.SetUse( TCoeColorUse::EFore|TCoeColorUse::EActive|TCoeColorUse::EHighlights|commonAttributes ); |
|
6532 aColorUseList.AppendL(colorUse); |
|
6533 |
|
6534 colorUse.SetLogicalColor( EColorMenuPaneHighlight ); |
|
6535 colorUse.SetUse(TCoeColorUse::EBack|TCoeColorUse::EActive|TCoeColorUse::EHighlights|commonAttributes ); |
|
6536 aColorUseList.AppendL( colorUse ); |
|
6537 |
|
6538 colorUse.SetLogicalColor( EColorMenuPaneDimmedTextHighlight ); |
|
6539 colorUse.SetUse( TCoeColorUse::EBack|TCoeColorUse::EDimmed|TCoeColorUse::EHighlights|commonAttributes ); |
|
6540 aColorUseList.AppendL( colorUse ); |
|
6541 |
|
6542 colorUse.SetLogicalColor( EColorMenuPaneDimmedHighlight ); |
|
6543 colorUse.SetUse( TCoeColorUse::EFore|TCoeColorUse::EDimmed|TCoeColorUse::EHighlights|commonAttributes ); |
|
6544 aColorUseList.AppendL( colorUse ); |
|
6545 |
|
6546 colorUse.SetLogicalColor( EColorMenuPaneDimmedText ); |
|
6547 colorUse.SetUse( TCoeColorUse::EBack|TCoeColorUse::EDimmed|TCoeColorUse::ESurrounds|commonAttributes); |
|
6548 aColorUseList.AppendL( colorUse ); |
|
6549 } |
|
6550 |
|
6551 |
|
6552 // ----------------------------------------------------------------------------- |
|
6553 // CEikMenuPane::HandleResourceChange |
|
6554 // Handles a change to the control's resources of type aType |
|
6555 // which are shared across the environment, e.g. colors or fonts. |
|
6556 // |
|
6557 // @since ER5U |
|
6558 // ----------------------------------------------------------------------------- |
|
6559 // |
|
6560 EXPORT_C void CEikMenuPane::HandleResourceChange( TInt aType ) |
|
6561 { |
|
6562 _AKNTRACE_FUNC_ENTER; |
|
6563 _AKNTRACE( "aType= %d", aType ); |
|
6564 if ( aType == KEikDynamicLayoutVariantSwitch ) |
|
6565 { |
|
6566 if ( IsActivated() ) |
|
6567 { |
|
6568 TInt maxItems = NumberOfItemsThatFitInView(); |
|
6569 TInt topIndex = iScroller->TopItemIndex(); |
|
6570 TInt count = iItemArray->Count(); |
|
6571 if ( count <= maxItems ) |
|
6572 { |
|
6573 iScroller->SetTopItemIndex( 0 ); |
|
6574 topIndex = iScroller->TopItemIndex(); |
|
6575 } |
|
6576 //In portrait mode. |
|
6577 if ( !Layout_Meta_Data::IsLandscapeOrientation() ) |
|
6578 { |
|
6579 if( ( count > maxItems ) && ( count - topIndex < maxItems ) ) |
|
6580 { |
|
6581 TInt maxItemGaps = maxItems - (count - topIndex); |
|
6582 iScroller->SetTopItemIndex( topIndex - maxItemGaps ); |
|
6583 topIndex = iScroller->TopItemIndex(); |
|
6584 } |
|
6585 } |
|
6586 TInt index = iSelectedItem - topIndex; |
|
6587 if ( index >= maxItems ) |
|
6588 { |
|
6589 topIndex = topIndex + (index + 1 - maxItems); |
|
6590 iScroller->SetTopItemIndex( topIndex ); |
|
6591 } |
|
6592 |
|
6593 TRect rect( CalculateSizeAndPosition() ); |
|
6594 SetExtent( rect.iTl, rect.Size() ); |
|
6595 |
|
6596 TRAP_IGNORE( DoUpdateScrollBarL() ); |
|
6597 |
|
6598 UpdateBackgroundContext( Rect() ); |
|
6599 PrepareHighlightFrame(); |
|
6600 SetCascadedIconSize(); |
|
6601 |
|
6602 // Background under highlight may have changed -> we need to update |
|
6603 // highlight background to animation |
|
6604 if( iExtension ) |
|
6605 { |
|
6606 iExtension->HandleLayoutSwitch(); |
|
6607 } |
|
6608 |
|
6609 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6610 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
6611 if ( transApi ) |
|
6612 { |
|
6613 transApi->Remove( MAknListBoxTfxInternal:: EListEverything ); |
|
6614 } |
|
6615 #endif |
|
6616 |
|
6617 //Initialize physics engine |
|
6618 if ( iExtension->iPhysics ) |
|
6619 { |
|
6620 TRAP_IGNORE ( iExtension->InitPhysicsL() ); |
|
6621 iExtension->iListTopIndex = iScroller->TopItemIndex() * iItemHeight; |
|
6622 iExtension->iViewPosition.iY = |
|
6623 iExtension->iListTopIndex + iExtension->iViewHeight / 2; |
|
6624 iExtension->ViewPositionChanged( iExtension->iViewPosition ); |
|
6625 } |
|
6626 |
|
6627 if ( iCascadeMenuPane ) |
|
6628 { |
|
6629 iCascadeMenuPane->HandleResourceChange( aType ); |
|
6630 } |
|
6631 |
|
6632 } |
|
6633 } |
|
6634 else if( aType == KEikMessageUnfadeWindows |
|
6635 || aType == KEikMessageWindowsFadeChange |
|
6636 || aType == KEikMessageFadeAllWindows ) |
|
6637 { |
|
6638 //Fix for ELYG-7DR5UF |
|
6639 if ( IsActivated() ) |
|
6640 { |
|
6641 CEikScrollBar *verScrollBar = iSBFrame->VerticalScrollBar(); |
|
6642 if ( verScrollBar != NULL |
|
6643 && iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn ) |
|
6644 { |
|
6645 //iLastPointerEvent:Menu pane save the last pointer event in this |
|
6646 // variable every time in HandlePointerEvent(). |
|
6647 if ( verScrollBar->Rect().Contains( iExtension->iLastPointerEvent.iPosition ) && |
|
6648 ( iExtension->iLastPointerEvent.iType == TPointerEvent::EButton1Down |
|
6649 || iExtension->iLastPointerEvent.iType == TPointerEvent::EDrag ) ) |
|
6650 { |
|
6651 TPointerEvent pointerEvent = iExtension->iLastPointerEvent; |
|
6652 pointerEvent.iType = TPointerEvent::EButton1Up; |
|
6653 // Sending a up event to scroll bar for dehighlighting |
|
6654 // the scroll bar. |
|
6655 verScrollBar->HandlePointerEventL(pointerEvent); |
|
6656 iSBFrame->DrawScrollBarsDeferred(); |
|
6657 ClaimPointerGrab( EFalse ); |
|
6658 } |
|
6659 } |
|
6660 // Fixed for TSW error ELLI-7UG89S |
|
6661 if ( iExtension && iExtension->iPressedDown ) |
|
6662 { |
|
6663 iExtension->iPressedDown = EFalse; |
|
6664 DrawNow(); |
|
6665 } |
|
6666 if ( iCascadeMenuPane ) |
|
6667 { |
|
6668 iCascadeMenuPane->HandleResourceChange( aType ); |
|
6669 } |
|
6670 } |
|
6671 } |
|
6672 else if ( aType == KAknMessageFocusLost ) |
|
6673 { |
|
6674 if ( iExtension && iExtension->HighlightEnabled() ) |
|
6675 { |
|
6676 iExtension->EnableHighlight( EFalse, EFalse ); |
|
6677 DrawItem( iSelectedItem, ENoHighlight ); |
|
6678 } |
|
6679 } |
|
6680 else |
|
6681 { |
|
6682 CCoeControl::HandleResourceChange( aType ); |
|
6683 if ( aType == KAknsMessageSkinChange ) |
|
6684 { |
|
6685 // fixed for TSW error ECGO-7NZCPR. |
|
6686 SetCascadedIconSize(); |
|
6687 DrawDeferred(); |
|
6688 } |
|
6689 } |
|
6690 |
|
6691 // Note: Animation is skin dependent, but it exists only when the menu is |
|
6692 // displayed (additionally, inactive menupane simply won't receive skin |
|
6693 // change event). |
|
6694 _AKNTRACE_FUNC_EXIT; |
|
6695 } |
|
6696 |
|
6697 |
|
6698 // ----------------------------------------------------------------------------- |
|
6699 // CEikMenuPane::InsertMenuItemL |
|
6700 // ----------------------------------------------------------------------------- |
|
6701 // |
|
6702 EXPORT_C void CEikMenuPane::InsertMenuItemL(const CEikMenuPaneItem::SData& aMenuItem, TInt aPosition) |
|
6703 { |
|
6704 if ( !iItemArray ) |
|
6705 CreateItemArrayL(); |
|
6706 CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem(); |
|
6707 item->iData = aMenuItem; |
|
6708 iItemArray->InsertL( aPosition, item ); |
|
6709 UpdateScrollBar(); |
|
6710 } |
|
6711 |
|
6712 // ----------------------------------------------------------------------------- |
|
6713 // CEikMenuPane::MenuItemExists |
|
6714 // ----------------------------------------------------------------------------- |
|
6715 // |
|
6716 EXPORT_C TBool CEikMenuPane::MenuItemExists( TInt aCommandId, TInt& aPosition ) |
|
6717 { |
|
6718 TInt count(0); |
|
6719 if( iItemArray ) |
|
6720 count = iItemArray->Count(); |
|
6721 aPosition = 0; |
|
6722 CEikMenuPaneItem* item; |
|
6723 FOREVER |
|
6724 { |
|
6725 if ( aPosition == count ) |
|
6726 return EFalse; |
|
6727 item =(*iItemArray)[aPosition]; |
|
6728 if ( item->iData.iCommandId == aCommandId ) |
|
6729 break; |
|
6730 ++aPosition; |
|
6731 } |
|
6732 return ETrue; |
|
6733 } |
|
6734 |
|
6735 // ----------------------------------------------------------------------------- |
|
6736 // CEikMenuPane::IsCascadeMenuPane |
|
6737 // ----------------------------------------------------------------------------- |
|
6738 // |
|
6739 EXPORT_C TBool CEikMenuPane::IsCascadeMenuPane() const |
|
6740 { |
|
6741 return iOwner != NULL; |
|
6742 } |
|
6743 |
|
6744 // ----------------------------------------------------------------------------- |
|
6745 // CEikMenuPane::CascadeMenuPane |
|
6746 // ----------------------------------------------------------------------------- |
|
6747 // |
|
6748 EXPORT_C CEikMenuPane* CEikMenuPane::CascadeMenuPane() |
|
6749 { |
|
6750 return iCascadeMenuPane; |
|
6751 } |
|
6752 |
|
6753 // ----------------------------------------------------------------------------- |
|
6754 // CEikMenuPane::ItemDataByIndexL |
|
6755 // Gets a reference to the data in the specified menu item. |
|
6756 // ----------------------------------------------------------------------------- |
|
6757 // |
|
6758 EXPORT_C CEikMenuPaneItem::SData& CEikMenuPane::ItemDataByIndexL(TInt aItemIndex) |
|
6759 { |
|
6760 __ASSERT_ALWAYS( iItemArray, Panic( EEikPanicInvalidIndex ) ); |
|
6761 if ( aItemIndex < 0 || aItemIndex >= iItemArray->Count() ) |
|
6762 { |
|
6763 User::Leave( KErrArgument ); |
|
6764 } |
|
6765 |
|
6766 CEikMenuPaneItem* item = (*iItemArray)[aItemIndex]; |
|
6767 return item->iData; |
|
6768 } |
|
6769 |
|
6770 |
|
6771 // ----------------------------------------------------------------------------- |
|
6772 // CEikMenuPane::LoadCascadeBitmapL |
|
6773 // ----------------------------------------------------------------------------- |
|
6774 // |
|
6775 void CEikMenuPane::LoadCascadeBitmapL() |
|
6776 { |
|
6777 if ( iExtension ) |
|
6778 { |
|
6779 if ( iExtension->iCascadeBitmap ) |
|
6780 { |
|
6781 delete iExtension->iCascadeBitmap; |
|
6782 iExtension->iCascadeBitmap = NULL; |
|
6783 } |
|
6784 if ( iExtension->iCascadeBitmapMask ) |
|
6785 { |
|
6786 delete iExtension->iCascadeBitmapMask; |
|
6787 iExtension->iCascadeBitmapMask = NULL; |
|
6788 } |
|
6789 |
|
6790 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
6791 |
|
6792 AknsUtils::CreateIconL( skin, KAknsIIDQgnIndiSubmenu, iExtension->iCascadeBitmap, |
|
6793 iExtension->iCascadeBitmapMask, KAvkonBitmapFile, |
|
6794 EMbmAvkonQgn_indi_submenu, EMbmAvkonQgn_indi_submenu_mask ); |
|
6795 |
|
6796 } |
|
6797 } |
|
6798 |
|
6799 |
|
6800 // ----------------------------------------------------------------------------- |
|
6801 // CEikMenuPane::LoadCheckMarkBitmapL |
|
6802 // Creates the bitmap and the mask for check mark icon |
|
6803 // ----------------------------------------------------------------------------- |
|
6804 // |
|
6805 void CEikMenuPane::LoadCheckMarkBitmapL() |
|
6806 { |
|
6807 if ( iExtension ) |
|
6808 { |
|
6809 if ( iExtension->iCheckMarkBitmap ) |
|
6810 { |
|
6811 delete iExtension->iCheckMarkBitmap; |
|
6812 iExtension->iCheckMarkBitmap = NULL; |
|
6813 } |
|
6814 if ( iExtension->iCheckMarkBitmapMask ) |
|
6815 { |
|
6816 delete iExtension->iCheckMarkBitmapMask; |
|
6817 iExtension->iCheckMarkBitmapMask = NULL; |
|
6818 } |
|
6819 |
|
6820 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
6821 |
|
6822 AknsUtils::CreateIconL( skin, KAknsIIDQgnPropSubMarked, iExtension->iCheckMarkBitmap, |
|
6823 iExtension->iCheckMarkBitmapMask, KAvkonBitmapFile, |
|
6824 EMbmAvkonQgn_prop_sub_marked, EMbmAvkonQgn_prop_sub_marked_mask ); |
|
6825 |
|
6826 } |
|
6827 } |
|
6828 |
|
6829 |
|
6830 // ----------------------------------------------------------------------------- |
|
6831 // CEikMenuPane::MenuHasCheckBoxOn |
|
6832 // @return ETrue if at least one of the items has a check box to be on |
|
6833 // ----------------------------------------------------------------------------- |
|
6834 // |
|
6835 TBool CEikMenuPane::MenuHasCheckBoxOn() const |
|
6836 { |
|
6837 for (TInt i = 0; i < iItemArray->Count(); i++) |
|
6838 { |
|
6839 CEikMenuPaneItem* item=(*iItemArray)[i]; |
|
6840 if ( item->iData.iFlags&EEikMenuItemCheckBox && item->iData.iFlags&EEikMenuItemSymbolOn ) |
|
6841 return ETrue; |
|
6842 } |
|
6843 return EFalse; |
|
6844 } |
|
6845 |
|
6846 // ----------------------------------------------------------------------------- |
|
6847 // CEikMenuPane::LoadRadioButtonBitmapL |
|
6848 // Loads the bitmap and the mask for radio button icon |
|
6849 // ----------------------------------------------------------------------------- |
|
6850 // |
|
6851 void CEikMenuPane::LoadRadioButtonBitmapL() |
|
6852 { |
|
6853 if ( iExtension ) |
|
6854 { |
|
6855 if ( iExtension->iRadioButtonBitmap ) |
|
6856 { |
|
6857 delete iExtension->iRadioButtonBitmap; |
|
6858 iExtension->iRadioButtonBitmap = NULL; |
|
6859 } |
|
6860 if ( iExtension->iRadioButtonBitmapMask ) |
|
6861 { |
|
6862 delete iExtension->iRadioButtonBitmapMask; |
|
6863 iExtension->iRadioButtonBitmapMask = NULL; |
|
6864 } |
|
6865 |
|
6866 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
6867 |
|
6868 AknsUtils::CreateIconL( skin, KAknsIIDQgnPropSubCurrent, iExtension->iRadioButtonBitmap, |
|
6869 iExtension->iRadioButtonBitmapMask, KAvkonBitmapFile, |
|
6870 EMbmAvkonQgn_prop_sub_current, EMbmAvkonQgn_prop_sub_current_mask ); |
|
6871 |
|
6872 } |
|
6873 } |
|
6874 |
|
6875 |
|
6876 // ----------------------------------------------------------------------------- |
|
6877 // CEikMenuPane::IsItemMemberOfRadioButtonGroup |
|
6878 // @return ETrue if the item in submenu is the member of the radio button group |
|
6879 // ----------------------------------------------------------------------------- |
|
6880 // |
|
6881 TBool CEikMenuPane::IsItemMemberOfRadioButtonGroup(TInt aItem) const |
|
6882 { |
|
6883 if ( !( Extension()->iHasRadioGroup ) ) |
|
6884 { |
|
6885 return EFalse; |
|
6886 } |
|
6887 |
|
6888 if (aItem < 0 || aItem >= iItemArray->Count()) |
|
6889 { |
|
6890 return EFalse; |
|
6891 } |
|
6892 |
|
6893 CEikMenuPaneItem* item = (*iItemArray)[aItem]; |
|
6894 |
|
6895 if ( item->iData.iFlags&( EEikMenuItemRadioStart|EEikMenuItemRadioMiddle|EEikMenuItemRadioEnd ) ) |
|
6896 { |
|
6897 return ETrue; |
|
6898 } |
|
6899 |
|
6900 for ( TInt i = aItem; i >= 0; i-- ) |
|
6901 { |
|
6902 // try to find the beginning of radio button group, otherwise this item is before radio button group |
|
6903 CEikMenuPaneItem* previuosItem = (*iItemArray)[i]; |
|
6904 if (previuosItem->iData.iFlags&EEikMenuItemRadioStart) |
|
6905 { |
|
6906 return ETrue; |
|
6907 } |
|
6908 } |
|
6909 return EFalse; |
|
6910 } |
|
6911 |
|
6912 |
|
6913 // ----------------------------------------------------------------------------- |
|
6914 // CEikMenuPane::MenuHasIcon |
|
6915 // @return ETrue if at least one of the menu items has some icon to be drawn before the text. |
|
6916 // It is needed for DrawItem() function to move the text of all items right or left depending on the layout. |
|
6917 // If the menu doesn't contain any icons then text is positioned as in normal situation. |
|
6918 // ----------------------------------------------------------------------------- |
|
6919 // |
|
6920 TBool CEikMenuPane::MenuHasIcon() const |
|
6921 { |
|
6922 TBool retValue = EFalse; |
|
6923 // only submenus might contain radio button or check box |
|
6924 if ( iOwner && iExtension ) |
|
6925 { |
|
6926 retValue = ( (iExtension->iHasRadioGroup) || MenuHasCheckBoxOn() ); |
|
6927 } |
|
6928 return retValue; |
|
6929 } |
|
6930 |
|
6931 |
|
6932 // ----------------------------------------------------------------------------- |
|
6933 // CEikMenuPane::CalculateSizeAndPositionScalable |
|
6934 // Calculate size and position of a menu if scalable layouts are available. |
|
6935 // Also sets the rectangular for the menu pane |
|
6936 // ----------------------------------------------------------------------------- |
|
6937 // |
|
6938 TRect CEikMenuPane::CalculateSizeAndPositionScalable( const TRect& aWindowRect, TInt aNumItemsInPane ) |
|
6939 { |
|
6940 __ASSERT_ALWAYS( iExtension, Panic( EEikPanicNullPointer ) ); |
|
6941 _AKNTRACE_FUNC_ENTER; |
|
6942 TRect retVal; |
|
6943 |
|
6944 // it can be only in submenu in case when scalable layout is available |
|
6945 TBool hasIcon = MenuHasIcon(); |
|
6946 TBool hasDoubleSpanScrollBar = EFalse; |
|
6947 |
|
6948 if ( iSBFrame && iSBFrame->VScrollBarVisibility() ) |
|
6949 { |
|
6950 _AKNTRACE( "[%s]", "hasDoubleSpanScrollBar = ETrue;" ); |
|
6951 hasDoubleSpanScrollBar = ETrue; |
|
6952 } |
|
6953 |
|
6954 TRect parentMenuRect; |
|
6955 AknLayoutUtils::TAknCbaLocation cbaPosition = AknLayoutUtils::CbaLocation(); |
|
6956 |
|
6957 if ( !iOwner ) |
|
6958 { |
|
6959 _AKNTRACE( "[%s]", "the laylout of mainmenu" ); |
|
6960 TAknLayoutRect parentMenuLayoutRect; // popup_menu_window |
|
6961 |
|
6962 // This is a parent menu pane |
|
6963 |
|
6964 // Number of items and cba position tells the right layout for menu pane. |
|
6965 // Constants (33, 20, 7) and calculations are based on to the variants of the layout data. |
|
6966 switch ( cbaPosition ) |
|
6967 { |
|
6968 case AknLayoutUtils::EAknCbaLocationLeft: |
|
6969 { |
|
6970 _AKNTRACE( "[%s]", "AknLayoutUtils::EAknCbaLocationLeft" ); |
|
6971 switch ( aNumItemsInPane ) |
|
6972 { |
|
6973 case 7: |
|
6974 case 8: |
|
6975 { |
|
6976 parentMenuLayoutRect.LayoutRect( aWindowRect, |
|
6977 AknLayoutScalable_Avkon::popup_menu_window(37 + aNumItemsInPane).LayoutLine()); |
|
6978 |
|
6979 break; |
|
6980 } |
|
6981 default: |
|
6982 parentMenuLayoutRect.LayoutRect( aWindowRect, |
|
6983 AknLayoutScalable_Avkon::popup_menu_window(33 - aNumItemsInPane).LayoutLine()); |
|
6984 break; |
|
6985 } |
|
6986 break; |
|
6987 } |
|
6988 case AknLayoutUtils::EAknCbaLocationRight: |
|
6989 { |
|
6990 _AKNTRACE( "[%s]", "AknLayoutUtils::EAknCbaLocationRight" ); |
|
6991 TRect windowRect; |
|
6992 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, windowRect ); |
|
6993 |
|
6994 switch ( aNumItemsInPane ) |
|
6995 { |
|
6996 case 7: |
|
6997 case 8: |
|
6998 { |
|
6999 parentMenuLayoutRect.LayoutRect( windowRect, |
|
7000 AknLayoutScalable_Avkon::popup_menu_window(35 + aNumItemsInPane).LayoutLine()); |
|
7001 break; |
|
7002 } |
|
7003 default: |
|
7004 parentMenuLayoutRect.LayoutRect( windowRect, |
|
7005 AknLayoutScalable_Avkon::popup_menu_window(20 - aNumItemsInPane).LayoutLine()); |
|
7006 break; |
|
7007 } |
|
7008 break; |
|
7009 } |
|
7010 case AknLayoutUtils::EAknCbaLocationBottom: |
|
7011 { |
|
7012 _AKNTRACE( "[%s]", "AknLayoutUtils::EAknCbaLocationBottom" ); |
|
7013 switch ( aNumItemsInPane ) |
|
7014 { |
|
7015 case 7: |
|
7016 case 8: |
|
7017 { |
|
7018 parentMenuLayoutRect.LayoutRect( aWindowRect, |
|
7019 AknLayoutScalable_Avkon::popup_menu_window(33 + aNumItemsInPane).LayoutLine()); |
|
7020 break; |
|
7021 } |
|
7022 default: |
|
7023 parentMenuLayoutRect.LayoutRect( aWindowRect, |
|
7024 AknLayoutScalable_Avkon::popup_menu_window(7 + aNumItemsInPane).LayoutLine()); |
|
7025 break; |
|
7026 } |
|
7027 break; |
|
7028 } |
|
7029 default: |
|
7030 break; |
|
7031 } |
|
7032 parentMenuRect = parentMenuLayoutRect.Rect(); |
|
7033 } |
|
7034 else |
|
7035 { |
|
7036 _AKNTRACE( "[%s]", "the layout of submenu" ); |
|
7037 // submenu |
|
7038 parentMenuRect = TRect( iOwner->Position(), iOwner->Size() ); |
|
7039 } |
|
7040 |
|
7041 _AKNTRACE( "parentMenuRect.iTl.iX = %d", parentMenuRect.iTl.iX ); |
|
7042 _AKNTRACE( "parentMenuRect.iTl.iY = %d", parentMenuRect.iTl.iY ); |
|
7043 _AKNTRACE( "parentMenuRect.Width() = %d", parentMenuRect.Width() ); |
|
7044 _AKNTRACE( "parentMenuRect.Height( = %d", parentMenuRect.Height() ); |
|
7045 // if we have landscape layout then main menu should be positioned vertically centered |
|
7046 TRect appRect( iEikonEnv->EikAppUi()->ApplicationRect() ); |
|
7047 |
|
7048 if ( !iOwner ) // main menu |
|
7049 { |
|
7050 // Embedded cba |
|
7051 TRect screen; |
|
7052 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); |
|
7053 |
|
7054 TAknLayoutRect cbaRect; |
|
7055 cbaRect.LayoutRect( screen, |
|
7056 AknLayoutScalable_Avkon::popup_sk_window( 0 ).LayoutLine() ); |
|
7057 |
|
7058 // Add space for embedded cba |
|
7059 TRect menuRect ( parentMenuRect ); |
|
7060 parentMenuRect.iBr.iY += ( cbaRect.Rect().Height() ); |
|
7061 |
|
7062 // CEikMenuPane rect contains empty space. We want the popup content |
|
7063 // to be in correct place - so we calculate correct position for |
|
7064 // background and move control rect to match new background top left |
|
7065 // position. |
|
7066 TRect backgroundRect( iExtension->GetBackgroundRect( parentMenuRect ) ); |
|
7067 TPoint backgroundRectPos( |
|
7068 AknPopupUtils::Position( backgroundRect.Size(), ETrue ) ); |
|
7069 |
|
7070 retVal = parentMenuRect; |
|
7071 retVal.Move( backgroundRectPos - backgroundRect.iTl ); |
|
7072 |
|
7073 // Set embedded cba rect |
|
7074 if ( iExtension->iCba ) |
|
7075 { |
|
7076 // There is hidden extra touch space for scroll bar in landscape |
|
7077 TInt xOffset = backgroundRect.iTl.iX - parentMenuRect.iTl.iX ; |
|
7078 iExtension->iCba->SetRect( TRect( |
|
7079 xOffset, |
|
7080 menuRect.Height(), |
|
7081 backgroundRect.Width() + xOffset, |
|
7082 menuRect.Height() + cbaRect.Rect().Height() ) ); |
|
7083 } |
|
7084 |
|
7085 iExtension->iMenuPaneRect = TRect( retVal.iTl, |
|
7086 TSize ( menuRect.Size() ) ); |
|
7087 |
|
7088 _AKNTRACE( "[%s]", "the layout of main menu return" ); |
|
7089 _AKNTRACE_FUNC_EXIT; |
|
7090 return retVal; |
|
7091 } |
|
7092 |
|
7093 // This is a cascaded sub menu |
|
7094 // Get a rectangle for the Parent Menu (iOwner) |
|
7095 TInt parentCount = iOwner->iItemArray->Count(); // There must be at least one parent item for a submenu to have popped up. |
|
7096 |
|
7097 iExtension->iSubMenuWidthIndex = KAlternativeSubmenuWidths - 1; |
|
7098 |
|
7099 TAknLayoutRect parentListScrollLayoutRect; // listscroll_menu_pane |
|
7100 TAknLayoutRect parentPaneLayoutRect; // list_menu_pane |
|
7101 |
|
7102 TAknTextLineLayout subMenuText; // layout for the text when item is not indicated |
|
7103 TAknTextLineLayout subMenuIconText; // layout for the text when item is indicated |
|
7104 |
|
7105 TAknWindowLineLayout parentListScrollPaneLayout( |
|
7106 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
7107 if ( iExtension ) |
|
7108 { |
|
7109 iExtension->AdjustPopupLayoutData( parentListScrollPaneLayout ); |
|
7110 } |
|
7111 parentListScrollLayoutRect.LayoutRect( parentMenuRect, parentListScrollPaneLayout ); |
|
7112 parentPaneLayoutRect.LayoutRect( parentListScrollLayoutRect.Rect(), |
|
7113 AknLayoutScalable_Avkon::list_menu_pane(0).LayoutLine() ); |
|
7114 subMenuText = AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1(0).LayoutLine(); |
|
7115 subMenuIconText = AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1(1).LayoutLine(); |
|
7116 |
|
7117 // Choose correct submenu width |
|
7118 // Find the narrowest layout that will accommodate the text |
|
7119 // Need the font. |
|
7120 const CFont* font = AknLayoutUtils::FontFromId( subMenuIconText.FontId() ); |
|
7121 // find the longest piece of text |
|
7122 TInt textWidth = 0; |
|
7123 TInt maxTextWidth = 0; |
|
7124 TInt ii = 0; |
|
7125 |
|
7126 TInt count = (NULL != iItemArray) ? iItemArray->Count() : 0; |
|
7127 |
|
7128 for (ii = 0; ii < count; ++ii) |
|
7129 { |
|
7130 CEikMenuPaneItem* item = (*iItemArray)[ii]; |
|
7131 textWidth = font->TextWidthInPixels( item->iData.iText ); |
|
7132 maxTextWidth = Max( maxTextWidth, textWidth ); |
|
7133 } |
|
7134 |
|
7135 // find the suitable item width, so that the text would be visible |
|
7136 for ( ii = 6; ii < KAlternativeSubmenuWidths + 6; ++ii ) |
|
7137 { |
|
7138 TAknWindowLineLayout submenuLayout( AknLayoutScalable_Avkon::popup_submenu_window( ii ).LayoutLine() ); |
|
7139 TAknLayoutRect submenuRect; |
|
7140 submenuRect.LayoutRect( parentListScrollLayoutRect.Rect(), submenuLayout ); |
|
7141 |
|
7142 TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); |
|
7143 TAknLayoutRect listScrollPaneRect; |
|
7144 listScrollPaneRect.LayoutRect( submenuRect.Rect(), listScrollPaneLayout ); |
|
7145 |
|
7146 TAknWindowLineLayout listSubmenuPaneLayout( AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine() ); |
|
7147 TAknLayoutRect listSubmenuPaneRect; |
|
7148 listSubmenuPaneRect.LayoutRect( listScrollPaneRect.Rect(), listSubmenuPaneLayout ); |
|
7149 |
|
7150 TAknLayoutText textIconLayout; |
|
7151 textIconLayout.LayoutText( listSubmenuPaneRect.Rect(), subMenuIconText); |
|
7152 |
|
7153 TAknLayoutText textLayout; |
|
7154 textLayout.LayoutText( listSubmenuPaneRect.Rect(), subMenuText); |
|
7155 |
|
7156 TInt width = textLayout.TextRect().Width(); |
|
7157 TInt maxWidth( maxTextWidth ); |
|
7158 |
|
7159 if ( hasIcon ) |
|
7160 { |
|
7161 // this is needed to calculate right index, because they are for the case when there is no indication |
|
7162 TInt difference = textIconLayout.TextRect().iTl.iX - textLayout.TextRect().iTl.iX; |
|
7163 maxWidth = maxTextWidth + difference; |
|
7164 width = textIconLayout.TextRect().Width(); |
|
7165 } |
|
7166 |
|
7167 if ( width >= maxWidth) |
|
7168 { |
|
7169 iExtension->iSubMenuWidthIndex = ii - 6; // finally we found one |
|
7170 break; |
|
7171 } |
|
7172 } |
|
7173 |
|
7174 // Position of submenu depends upon parent size and position of selected item. Position is 1 at bottom up to six at top |
|
7175 TInt parentPos = iOwner->iScroller->TopItemIndex() - iOwner->SelectedItem() + |
|
7176 Min( parentCount, iOwner->NumberOfItemsThatFitInView() ); |
|
7177 |
|
7178 TInt index = iOwner->SelectedItem() - iOwner->iScroller->TopItemIndex(); |
|
7179 TInt rows = AknLayoutScalable_Avkon::list_single_pane_cp2_ParamLimits().LastRow(); |
|
7180 |
|
7181 // This condition may be true if less items fits to menu view than sub-menu view |
|
7182 // and sub-menu under sub-menu is launched. |
|
7183 if (index > rows) |
|
7184 { |
|
7185 // Change the out-of-boundary index to last legal one. |
|
7186 index = rows; |
|
7187 } |
|
7188 |
|
7189 TAknLayoutRect parentSelectedItemRect; |
|
7190 parentSelectedItemRect.LayoutRect( parentPaneLayoutRect.Rect(), |
|
7191 AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine() ); |
|
7192 |
|
7193 TAknLayoutRect submenuWindowRect; |
|
7194 // To prevent a panic in layout code, count has to be at least 1 even if |
|
7195 // submenu is empty. Otherwise the index is out of bounds. |
|
7196 if ( count == 0 ) |
|
7197 { |
|
7198 count++; |
|
7199 } |
|
7200 TInt maxItems = NumberOfItemsThatFitInView(); |
|
7201 submenuWindowRect.LayoutRect( parentMenuRect, |
|
7202 AknLayoutScalable_Avkon::popup_submenu_window( Min( count, maxItems ) - 1 ).LayoutLine() ); |
|
7203 // if submenu is higher than main menu, we should not allow it to cover softkeys in landscape |
|
7204 // the same should be done if position of the menu was set from outside. |
|
7205 if ( ( Layout_Meta_Data::IsLandscapeOrientation() |
|
7206 && cbaPosition != AknLayoutUtils::EAknCbaLocationBottom && |
|
7207 ( submenuWindowRect.Rect().Height() > parentMenuRect.Height() ) ) ) |
|
7208 { |
|
7209 // submenu should stay inside main menu by width, |
|
7210 TRect bufRect( aWindowRect ); |
|
7211 bufRect.iTl.iX = parentMenuRect.iTl.iX; |
|
7212 bufRect.iBr.iX = parentMenuRect.iBr.iX; |
|
7213 submenuWindowRect.LayoutRect( bufRect, |
|
7214 AknLayoutScalable_Avkon::popup_submenu_window( Min( count, maxItems ) - 1 ).LayoutLine() ); |
|
7215 } |
|
7216 |
|
7217 TAknLayoutRect widthSubmenuRect; |
|
7218 widthSubmenuRect.LayoutRect( parentMenuRect, |
|
7219 AknLayoutScalable_Avkon::popup_submenu_window( iExtension->iSubMenuWidthIndex + 6 ).LayoutLine() ); |
|
7220 |
|
7221 TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); |
|
7222 TAknLayoutRect listScrollPaneRect; |
|
7223 listScrollPaneRect.LayoutRect( submenuWindowRect.Rect(), listScrollPaneLayout ); |
|
7224 |
|
7225 enum { EFloating, EBottom } subMenuPos; |
|
7226 |
|
7227 if ( ( Layout_Meta_Data::IsLandscapeOrientation() |
|
7228 && cbaPosition != AknLayoutUtils::EAknCbaLocationBottom ) ) |
|
7229 { |
|
7230 if ( ( parentSelectedItemRect.Rect().iTl.iY + submenuWindowRect.Rect().Height() ) > |
|
7231 aWindowRect.iBr.iY ) |
|
7232 { |
|
7233 subMenuPos = EBottom; |
|
7234 } |
|
7235 else |
|
7236 { |
|
7237 subMenuPos = EFloating; |
|
7238 } |
|
7239 } |
|
7240 else |
|
7241 { |
|
7242 if ( iOwner->iExtension->Offset() < 0 && |
|
7243 ((parentPos == 1 && count == 1) || |
|
7244 (parentPos == 2 && count <= 2) || |
|
7245 (parentPos == 3 && count <= 3) || |
|
7246 (parentPos == 4 && count <= 4) || |
|
7247 (parentPos == 5 && count <= 5) ) ) |
|
7248 { |
|
7249 // The menu has partial items because of panning and that has an effect on submenu positioning. |
|
7250 subMenuPos = EFloating; |
|
7251 } |
|
7252 else if (parentPos == 1 || |
|
7253 (parentPos ==2 && count >= 2) || |
|
7254 (parentPos == 3 && count >= 4) || |
|
7255 (parentPos == 4 && count >= 5) || |
|
7256 (parentPos == 5 && count >= 6) ) |
|
7257 { |
|
7258 subMenuPos = EBottom; |
|
7259 } |
|
7260 else |
|
7261 { |
|
7262 subMenuPos = EFloating; |
|
7263 } |
|
7264 } |
|
7265 |
|
7266 if ( subMenuPos == EBottom ) |
|
7267 { |
|
7268 TInt widthOffset = widthSubmenuRect.Rect().Width() - submenuWindowRect.Rect().Width(); |
|
7269 if ( !AknLayoutUtils::LayoutMirrored() ) |
|
7270 { |
|
7271 retVal = TRect( TPoint( submenuWindowRect.Rect().iTl.iX - widthOffset, submenuWindowRect.Rect().iTl.iY ), |
|
7272 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) ); |
|
7273 } |
|
7274 else |
|
7275 { |
|
7276 retVal = TRect( submenuWindowRect.Rect().iTl, |
|
7277 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) ); |
|
7278 } |
|
7279 } |
|
7280 else // floating |
|
7281 { |
|
7282 TInt yPos = parentSelectedItemRect.Rect().iTl.iY - |
|
7283 ( listScrollPaneRect.Rect().iTl.iY - submenuWindowRect.Rect().iTl.iY ); |
|
7284 |
|
7285 // When a submenu is floating, make sure that the possible panning offset of the |
|
7286 // parent menu is taken into account. |
|
7287 yPos += iOwner->iExtension->Offset(); |
|
7288 TInt widthOffset = widthSubmenuRect.Rect().Width() - submenuWindowRect.Rect().Width(); |
|
7289 if ( !AknLayoutUtils::LayoutMirrored() ) |
|
7290 { |
|
7291 retVal = TRect( TPoint( submenuWindowRect.Rect().iTl.iX - widthOffset, yPos ), |
|
7292 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) ); |
|
7293 } |
|
7294 else |
|
7295 { |
|
7296 retVal = TRect( TPoint( submenuWindowRect.Rect().iTl.iX, yPos ), |
|
7297 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) ); |
|
7298 } |
|
7299 } |
|
7300 |
|
7301 // move submenu if it overlaps with embedded cba |
|
7302 if ( iOwner && iOwner->iExtension->iCba ) |
|
7303 { |
|
7304 if ( retVal.iBr.iY > iOwner->iExtension->iMenuPaneRect.iBr.iY ) |
|
7305 { |
|
7306 TInt offset = retVal.iBr.iY - |
|
7307 iOwner->iExtension->iMenuPaneRect.iBr.iY; |
|
7308 retVal.Move( 0, -offset ); |
|
7309 } |
|
7310 } |
|
7311 _AKNTRACE( "[%s]", "the layout of sub menu return" ); |
|
7312 _AKNTRACE_FUNC_EXIT; |
|
7313 return retVal; |
|
7314 } |
|
7315 |
|
7316 // ----------------------------------------------------------------------------- |
|
7317 // CEikMenuPane::HighlightRect |
|
7318 // ----------------------------------------------------------------------------- |
|
7319 // |
|
7320 TRect CEikMenuPane::HighlightRect() const |
|
7321 { |
|
7322 TInt index = iSelectedItem - iScroller->TopItemIndex(); |
|
7323 |
|
7324 // If menu is closed and the selected item index is outside the visible |
|
7325 // item range this method is called with new iSelectedItem and old |
|
7326 // TopItemIndex. Which results in negative index. This "fix" prevents from |
|
7327 // crashing the menu. |
|
7328 if( index < 0 ) |
|
7329 index = 0; |
|
7330 |
|
7331 // It is possible that this method is called when iItemArray is NULL. In |
|
7332 // that case we fake numItems as 1 to make layout code work. |
|
7333 TInt maxItems = NumberOfItemsThatFitInView(); |
|
7334 TInt numItems = Min( Max( 1, iItemArray->Count() ), maxItems ); |
|
7335 if( !iItemArray ) |
|
7336 numItems = 1; |
|
7337 |
|
7338 // When physics is enabled highlight can be moved to partially visible |
|
7339 // item which is at the bottom of menu. This causes layout panic and to |
|
7340 // avoid that we reduce index by one. |
|
7341 if ( index == maxItems ) |
|
7342 { |
|
7343 index--; |
|
7344 } |
|
7345 |
|
7346 TRect windowRect = Rect(); |
|
7347 |
|
7348 TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) ); |
|
7349 TAknWindowLineLayout singleMenuPane( AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) ); |
|
7350 TAknLayoutRect menuPaneRect; |
|
7351 TAknLayoutRect singleMenuPaneRect; |
|
7352 |
|
7353 TBool hasDoubleSpanScrollBar = EFalse; |
|
7354 |
|
7355 if ( iSBFrame && iSBFrame->VScrollBarVisibility() ) |
|
7356 { |
|
7357 hasDoubleSpanScrollBar = ETrue; |
|
7358 } |
|
7359 |
|
7360 if ( !iOwner ) |
|
7361 { |
|
7362 TAknWindowLineLayout listScrollPaneLayout( |
|
7363 AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); |
|
7364 if ( iExtension ) |
|
7365 { |
|
7366 iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); |
|
7367 } |
|
7368 TAknLayoutRect listScrollPaneRect; |
|
7369 listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); |
|
7370 |
|
7371 menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); |
|
7372 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
7373 |
|
7374 singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine(); |
|
7375 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); |
|
7376 } |
|
7377 else // Submenu |
|
7378 { |
|
7379 TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); |
|
7380 TAknLayoutRect listScrollPaneRect; |
|
7381 listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); |
|
7382 |
|
7383 menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine(); |
|
7384 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); |
|
7385 |
|
7386 singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine(); |
|
7387 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); |
|
7388 } |
|
7389 |
|
7390 // Compared to normal DrawItem the highlight rect step is omitted because |
|
7391 // it would shift the highlight towards left. |
|
7392 |
|
7393 return singleMenuPaneRect.Rect(); |
|
7394 } |
|
7395 |
|
7396 |
|
7397 // ----------------------------------------------------------------------------- |
|
7398 // CEikMenuPane::PrepareHighlightFrame |
|
7399 // helps to avoid flickering on drawing |
|
7400 // ----------------------------------------------------------------------------- |
|
7401 // |
|
7402 void CEikMenuPane::PrepareHighlightFrame() const |
|
7403 { |
|
7404 TRect highlightRect( HighlightRect() ); |
|
7405 TAknLayoutRect highlightTopLeft; |
|
7406 TAknLayoutRect highlightBottomRight; |
|
7407 highlightTopLeft.LayoutRect( highlightRect, |
|
7408 SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() ); |
|
7409 highlightBottomRight.LayoutRect( highlightRect, |
|
7410 SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() ); |
|
7411 TRect outerRect = TRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr ); |
|
7412 TRect innerRect = TRect( highlightTopLeft.Rect().iBr, highlightBottomRight.Rect().iTl ); |
|
7413 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
7414 |
|
7415 AknsDrawUtils::PrepareFrame( skin, outerRect, innerRect, |
|
7416 KAknsIIDQsnFrList, KAknsIIDDefault ); |
|
7417 } |
|
7418 |
|
7419 // ----------------------------------------------------------------------------- |
|
7420 // CEikMenuPane::SetCascadedIconSize |
|
7421 // Calls SetSize for cascaded icon. Doing this in construction phase makes |
|
7422 // Draw() method faster. |
|
7423 // ----------------------------------------------------------------------------- |
|
7424 // |
|
7425 void CEikMenuPane::SetCascadedIconSize() const |
|
7426 { |
|
7427 TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine()); |
|
7428 TAknLayoutRect cascadeRect; |
|
7429 cascadeRect.LayoutRect( HighlightRect(), elementCascade ); |
|
7430 |
|
7431 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
7432 CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>( |
|
7433 skin->GetCachedItemData( KAknsIIDQgnIndiSubmenu, EAknsITMaskedBitmap ) ); |
|
7434 |
|
7435 if( itemData ) |
|
7436 { |
|
7437 AknIconUtils::SetSize( itemData->Bitmap(), cascadeRect.Rect().Size() ); |
|
7438 } |
|
7439 |
|
7440 else |
|
7441 { |
|
7442 if (iExtension->iCascadeBitmap) |
|
7443 { |
|
7444 AknIconUtils::SetSize( iExtension->iCascadeBitmap, cascadeRect.Rect().Size() ); |
|
7445 } |
|
7446 } |
|
7447 } |
|
7448 |
|
7449 |
|
7450 // ----------------------------------------------------------------------------- |
|
7451 // CEikMenuPane::EnableMarqueeL |
|
7452 // ----------------------------------------------------------------------------- |
|
7453 // |
|
7454 EXPORT_C void CEikMenuPane::EnableMarqueeL( const TBool /*aEnable*/ ) |
|
7455 { |
|
7456 } |
|
7457 |
|
7458 |
|
7459 // ----------------------------------------------------------------------------- |
|
7460 // CEikMenuPane::MopSupplyObject |
|
7461 // ----------------------------------------------------------------------------- |
|
7462 // |
|
7463 EXPORT_C TTypeUid::Ptr CEikMenuPane::MopSupplyObject( TTypeUid aId ) |
|
7464 { |
|
7465 if( aId.iUid == MAknsControlContext::ETypeId && iExtension && iExtension->iBgContext ) |
|
7466 { |
|
7467 // Supply background skin context for scroll bars. |
|
7468 return MAknsControlContext::SupplyMopObject( aId, iExtension->iBgContext); |
|
7469 } |
|
7470 |
|
7471 return CCoeControl::MopSupplyObject( aId ); |
|
7472 } |
|
7473 |
|
7474 |
|
7475 // ----------------------------------------------------------------------------- |
|
7476 // CEikMenuPane::CountComponentControls |
|
7477 // ----------------------------------------------------------------------------- |
|
7478 // |
|
7479 EXPORT_C TInt CEikMenuPane::CountComponentControls() const |
|
7480 { |
|
7481 TInt count = 0; |
|
7482 if ( iSBFrame && iSBFrame->VerticalScrollBar() && |
|
7483 !( iSBFrame->VerticalScrollBar()->OwnsWindow() ) ) |
|
7484 { |
|
7485 count = 1; |
|
7486 } |
|
7487 if ( iExtension->iSct ) |
|
7488 { |
|
7489 count++; |
|
7490 } |
|
7491 |
|
7492 if ( iExtension->iCba ) |
|
7493 { |
|
7494 count++; |
|
7495 } |
|
7496 |
|
7497 return count; |
|
7498 } |
|
7499 |
|
7500 // ----------------------------------------------------------------------------- |
|
7501 // CEikMenuPane::ComponentControl |
|
7502 // ----------------------------------------------------------------------------- |
|
7503 // |
|
7504 EXPORT_C CCoeControl* CEikMenuPane::ComponentControl( TInt aIndex ) const |
|
7505 { |
|
7506 switch ( aIndex) |
|
7507 { |
|
7508 case 0: |
|
7509 { |
|
7510 if ( iSBFrame && iSBFrame->VerticalScrollBar() && |
|
7511 !( iSBFrame->VerticalScrollBar()->OwnsWindow() ) ) |
|
7512 { |
|
7513 return iSBFrame->VerticalScrollBar(); |
|
7514 } |
|
7515 } |
|
7516 case 1: |
|
7517 { |
|
7518 if ( iExtension->iSct ) |
|
7519 { |
|
7520 return iExtension->iSct; |
|
7521 } |
|
7522 else if ( iExtension->iCba ) |
|
7523 { |
|
7524 return iExtension->iCba; |
|
7525 } |
|
7526 } |
|
7527 case 2: |
|
7528 { |
|
7529 if ( iExtension->iCba ) |
|
7530 { |
|
7531 return iExtension->iCba; |
|
7532 } |
|
7533 } |
|
7534 default: |
|
7535 { |
|
7536 return NULL; |
|
7537 } |
|
7538 } |
|
7539 } |
|
7540 |
|
7541 |
|
7542 // ----------------------------------------------------------------------------- |
|
7543 // CEikMenuPane::Extension |
|
7544 // Asserts that extension object has been created. |
|
7545 // ----------------------------------------------------------------------------- |
|
7546 // |
|
7547 CEikMenuPaneExtension* CEikMenuPane::Extension() const |
|
7548 { |
|
7549 __ASSERT_ALWAYS( iExtension, Panic( EEikPanicNullPointer ) ); |
|
7550 return iExtension; |
|
7551 } |
|
7552 |
|
7553 |
|
7554 void CEikMenuPane::CheckCreateExtensionL() |
|
7555 { |
|
7556 if ( !iExtension ) |
|
7557 { |
|
7558 iExtension = new (ELeave) CEikMenuPaneExtension; |
|
7559 iExtension->ConstructL( this ); |
|
7560 } |
|
7561 } |
|
7562 |
|
7563 |
|
7564 // ----------------------------------------------------------------------------- |
|
7565 // CEikMenuPane::ConstructMenuSctRowL |
|
7566 // Creates an sct row for editing menu. |
|
7567 // @param aSpecialChars Buffer that holds selected characters |
|
7568 // @since 3.1 |
|
7569 // ----------------------------------------------------------------------------- |
|
7570 // |
|
7571 EXPORT_C void CEikMenuPane::ConstructMenuSctRowL( TDes& aSpecialChars ) |
|
7572 { |
|
7573 CheckCreateScrollerL(); |
|
7574 CheckCreateExtensionL(); |
|
7575 |
|
7576 TInt resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS; |
|
7577 if (FeatureManager::FeatureSupported(KFeatureIdChinese)) |
|
7578 { |
|
7579 resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS_CHINESE; |
|
7580 } |
|
7581 iExtension->ConstructMenuSctRowL( aSpecialChars, resourceId ); |
|
7582 } |
|
7583 |
|
7584 // ----------------------------------------------------------------------------- |
|
7585 // CEikMenuPane::ConstructMenuSctRowL |
|
7586 // Creates an sct row for editing menu. |
|
7587 // @param aSpecialChars Buffer that holds selected characters |
|
7588 // @since 3.1 |
|
7589 // ----------------------------------------------------------------------------- |
|
7590 // |
|
7591 |
|
7592 EXPORT_C void CEikMenuPane::ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId ) |
|
7593 { |
|
7594 CheckCreateScrollerL(); |
|
7595 CheckCreateExtensionL(); |
|
7596 iExtension->ConstructMenuSctRowL( aSpecialChars, aResourceId ); |
|
7597 } |
|
7598 |
|
7599 // ----------------------------------------------------------------------------- |
|
7600 // CEikMenuPane::ConstructMenuSctRowFromDialogL |
|
7601 // Creates an sct row for editing menu. |
|
7602 // @param aSpecialChars Buffer that holds selected characters |
|
7603 // @since 3.1 |
|
7604 // ----------------------------------------------------------------------------- |
|
7605 // |
|
7606 EXPORT_C void CEikMenuPane::ConstructMenuSctRowFromDialogL( TDes& aSpecialChars, TInt aResourceId ) |
|
7607 { |
|
7608 CheckCreateScrollerL(); |
|
7609 CheckCreateExtensionL(); |
|
7610 iExtension->ConstructMenuSctRowFromDialogL( aSpecialChars, aResourceId ); |
|
7611 } |
|
7612 |
|
7613 // ----------------------------------------------------------------------------- |
|
7614 // CEikMenuPane::ConstructMenuSctRowFromDialogL |
|
7615 // Creates an sct row for editing menu. |
|
7616 // @param aSpecialChars Buffer that holds selected characters |
|
7617 // @since 3.1 |
|
7618 // ----------------------------------------------------------------------------- |
|
7619 // |
|
7620 EXPORT_C void CEikMenuPane::ConstructMenuSctRowFromDialogL( TInt aCharCase, TDes& aSpecialChars, TInt aResourceId ) |
|
7621 { |
|
7622 ConstructMenuSctRowFromDialogL( aSpecialChars, aResourceId); |
|
7623 iExtension->iSct->SetCharacterCaseL(aCharCase); |
|
7624 } |
|
7625 |
|
7626 |
|
7627 // ----------------------------------------------------------------------------- |
|
7628 // CEikMenuPane::SetItemSpecific |
|
7629 // ----------------------------------------------------------------------------- |
|
7630 // |
|
7631 EXPORT_C void CEikMenuPane::SetItemSpecific( |
|
7632 TInt aCommandId, TBool aItemSpecific ) |
|
7633 { |
|
7634 if ( iExtension->iFlags.IsSet( |
|
7635 CEikMenuPaneExtension::ESingleClickEnabled ) ) |
|
7636 { |
|
7637 CEikMenuPaneItem::SData& itemData = ItemData( aCommandId ); |
|
7638 if ( aItemSpecific ) |
|
7639 { |
|
7640 // item specific command cannot be item action command |
|
7641 itemData.iFlags &= ( ~EEikMenuItemAction ); |
|
7642 itemData.iFlags |= EEikMenuItemSpecific; |
|
7643 } |
|
7644 else |
|
7645 { |
|
7646 // clear both item specific flags |
|
7647 itemData.iFlags &= ( ~EEikMenuItemSpecific ); |
|
7648 itemData.iFlags &= ( ~EEikMenuItemSpecificListQuery ); |
|
7649 } |
|
7650 } |
|
7651 } |
|
7652 |
|
7653 |
|
7654 // ----------------------------------------------------------------------------- |
|
7655 // CEikMenuPane::MenuItemCommandId |
|
7656 // Returns the command id of the specified menu item. |
|
7657 // ----------------------------------------------------------------------------- |
|
7658 // |
|
7659 EXPORT_C TInt CEikMenuPane::MenuItemCommandId( const TInt aIndex ) const |
|
7660 { |
|
7661 if ( !iItemArray || aIndex >= iItemArray->Count() || aIndex < 0 ) |
|
7662 { |
|
7663 Panic( EEikPanicInvalidIndex ); |
|
7664 } |
|
7665 CEikMenuPaneItem* item = (*iItemArray)[aIndex]; |
|
7666 if ( !item ) |
|
7667 { |
|
7668 Panic( EEikPanicNullPointer ); |
|
7669 } |
|
7670 return item->iData.iCommandId; |
|
7671 } |
|
7672 |
|
7673 |
|
7674 // ----------------------------------------------------------------------------- |
|
7675 // CEikMenuPane::SetEmbeddedCba |
|
7676 // ----------------------------------------------------------------------------- |
|
7677 // |
|
7678 void CEikMenuPane::SetEmbeddedCba( CEikCba* aCba ) |
|
7679 { |
|
7680 if ( iExtension ) |
|
7681 { |
|
7682 iExtension->iCba = aCba; |
|
7683 } |
|
7684 } |
|
7685 |
|
7686 |
|
7687 // ----------------------------------------------------------------------------- |
|
7688 // CEikMenuPane::CloseCascadeMenu |
|
7689 // ----------------------------------------------------------------------------- |
|
7690 // |
|
7691 void CEikMenuPane::CloseCascadeMenu( TBool aMainMenuClosing ) |
|
7692 { |
|
7693 if ( iCascadeMenuPane == NULL ) |
|
7694 { |
|
7695 return; |
|
7696 } |
|
7697 if( iCascadeMenuPane->iCascadeMenuPane) |
|
7698 { |
|
7699 return iCascadeMenuPane->CloseCascadeMenu(); |
|
7700 } |
|
7701 |
|
7702 // This CloseCascadeMenu method is called from CEikMenuPane destructor. |
|
7703 // CEikMenuPane may be destroyed in AppUi's destructor. |
|
7704 // Thus, skin instance may not be valid any more when this function is called |
|
7705 // and all drawing should be avoided in such situation. |
|
7706 TBool okToDraw = EFalse; |
|
7707 |
|
7708 //iExtension->StartCascadeMenuDisappearTransition(); |
|
7709 if ( iCascadeMenuPane->IsVisible() ) |
|
7710 { |
|
7711 okToDraw = AknsUtils::SkinInstance() != NULL; |
|
7712 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
7713 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); |
|
7714 if ( transApi && okToDraw ) |
|
7715 { |
|
7716 iCascadeMenuPane->SetFocus( EFalse, EDrawNow ); |
|
7717 } |
|
7718 #endif |
|
7719 // Stop ongoing comp. transitions, this is mostly for fast clicking |
|
7720 // cases to make sure that no "scrap" is left behind. |
|
7721 GfxTransEffect::NotifyExternalState( ENotifyGlobalAbort ); |
|
7722 // cascade menu "cancel" animation. This does not apply |
|
7723 // when something is chosen from the menu |
|
7724 |
|
7725 if( iExtension->iShowCascadeTransition && okToDraw ) |
|
7726 { |
|
7727 iCascadeMenuPane->SetParent( this ); |
|
7728 |
|
7729 GfxTransEffect::Begin( iCascadeMenuPane, KGfxControlDisappearAction ); |
|
7730 GfxTransEffect::SetDemarcation( iCascadeMenuPane, iExtension->iCascadeDRect ); |
|
7731 |
|
7732 iCascadeMenuPane->MakeVisible( EFalse ); |
|
7733 |
|
7734 GfxTransEffect::End( iCascadeMenuPane ); |
|
7735 |
|
7736 } |
|
7737 } |
|
7738 |
|
7739 // deregister right away since cascade menu is deleted |
|
7740 GfxTransEffect::Deregister( iCascadeMenuPane ); |
|
7741 iExtension->iShowCascadeTransition = EFalse; |
|
7742 |
|
7743 //For transitions, keep the cascade menu object alive a little |
|
7744 // longer so that the transition system does not ever refer to |
|
7745 // deleted object |
|
7746 iExtension->iCascadeMenuObject = iCascadeMenuPane; |
|
7747 |
|
7748 |
|
7749 iCascadeMenuPane->MakeVisible( EFalse ); |
|
7750 iCascadeMenuPane = NULL; |
|
7751 |
|
7752 if ( !aMainMenuClosing ) |
|
7753 { |
|
7754 // Submenu is closed.Parent menu pane will grab window. |
|
7755 // ClaimPointerGrab invokes pointer up event. |
|
7756 ClaimPointerGrab(ETrue); |
|
7757 } |
|
7758 } |
|
7759 |
|
7760 |
|
7761 // ----------------------------------------------------------------------------- |
|
7762 // CEikMenuPane::NewItemCommandMenuL |
|
7763 // ----------------------------------------------------------------------------- |
|
7764 // |
|
7765 CEikMenuPane* CEikMenuPane::NewItemCommandMenuL( MEikMenuObserver* aObserver ) |
|
7766 { |
|
7767 CEikMenuPane* menuPane = new ( ELeave ) CEikMenuPane( aObserver ); |
|
7768 CleanupStack::PushL( menuPane ); |
|
7769 menuPane->iExtension = new ( ELeave ) CEikMenuPaneExtension(); |
|
7770 menuPane->iExtension->iFlags.Set( |
|
7771 CEikMenuPaneExtension::ESingleClickEnabled ); |
|
7772 menuPane->CreateItemArrayL(); |
|
7773 CleanupStack::Pop( menuPane ); |
|
7774 return menuPane; |
|
7775 } |
|
7776 |
|
7777 |
|
7778 // ----------------------------------------------------------------------------- |
|
7779 // CEikMenuPane::SetItemCommandsDimmed |
|
7780 // ----------------------------------------------------------------------------- |
|
7781 // |
|
7782 void CEikMenuPane::SetItemCommandsDimmed() |
|
7783 { |
|
7784 if ( iExtension && iExtension->iFlags.IsSet( |
|
7785 CEikMenuPaneExtension::ESingleClickEnabled ) ) |
|
7786 { |
|
7787 iExtension->iFlags.Set( |
|
7788 CEikMenuPaneExtension::EHideItemSpecificCommands ); |
|
7789 for ( TInt i = 0; i < iItemArray->Count(); ++i ) |
|
7790 { |
|
7791 CEikMenuPaneItem* item = iItemArray->At( i ); |
|
7792 if ( item->iData.iFlags & EEikMenuItemAction |
|
7793 || item->iData.iFlags & EEikMenuItemSpecific |
|
7794 || item->iData.iFlags & EEikMenuItemSpecificListQuery ) |
|
7795 { |
|
7796 item->iData.iFlags |= EEikMenuItemDimmed; |
|
7797 } |
|
7798 } |
|
7799 } |
|
7800 } |
|
7801 |
|
7802 |
|
7803 // ----------------------------------------------------------------------------- |
|
7804 // CEikMenuPane::AddMenuItemsToItemActionMenuL |
|
7805 // ----------------------------------------------------------------------------- |
|
7806 // |
|
7807 void CEikMenuPane::AddMenuItemsToItemActionMenuL( |
|
7808 CAknItemActionMenuData& aMenuData ) |
|
7809 { |
|
7810 TInt menuItemCount( iItemArray->Count() ); |
|
7811 for ( TInt i = 0; i < menuItemCount; ++i ) |
|
7812 { |
|
7813 CEikMenuPaneItem* item = iItemArray->At( i ); |
|
7814 // Add menu item if menu item is not dimmed and |
|
7815 // 1) menu item belongs to cascade menu |
|
7816 // 2) menu item is item specific command |
|
7817 // 3) menu item is item specific list query |
|
7818 if ( CEikMenuPaneExtension::ItemSpecificCommand( *item ) ) |
|
7819 { |
|
7820 // If menu item is not list query and it has cascade menu |
|
7821 // add cascade menu items to menu data directly |
|
7822 if ( !( item->iData.iFlags & EEikMenuItemSpecificListQuery ) |
|
7823 && item->iData.iCascadeId ) |
|
7824 { |
|
7825 AddCascadeMenuItemsToActionMenuL( |
|
7826 item->iData.iCascadeId, EFalse, aMenuData ); |
|
7827 } |
|
7828 // If menu item is list query or it does not have cascade menu |
|
7829 else |
|
7830 { |
|
7831 aMenuData.AddMenuItemToDataArrayL( |
|
7832 item->iData.iCommandId, |
|
7833 item->iData.iCascadeId, |
|
7834 item->iData.iText ); |
|
7835 } |
|
7836 } |
|
7837 // If item is not item specific, add its item specific cascade menu |
|
7838 // items if the item itself isn't dimmed. |
|
7839 else if ( item->iData.iCascadeId && |
|
7840 !( item->iData.iFlags & EEikMenuItemDimmed ) ) |
|
7841 { |
|
7842 AddCascadeMenuItemsToActionMenuL( |
|
7843 item->iData.iCascadeId, ETrue, aMenuData ); |
|
7844 } |
|
7845 } |
|
7846 } |
|
7847 |
|
7848 |
|
7849 // ----------------------------------------------------------------------------- |
|
7850 // CEikMenuPane::AddCascadeMenuItemsToActionMenuL |
|
7851 // ----------------------------------------------------------------------------- |
|
7852 // |
|
7853 void CEikMenuPane::AddCascadeMenuItemsToActionMenuL( |
|
7854 TInt aCascadeId, |
|
7855 TBool aItemSpecific, |
|
7856 CAknItemActionMenuData& aMenuData ) |
|
7857 { |
|
7858 if ( aCascadeId && iCoeEnv->IsResourceAvailableL( aCascadeId ) ) |
|
7859 { |
|
7860 CEikMenuPane* cascadeMenu = |
|
7861 CEikMenuPane::NewItemCommandMenuL( iMenuObserver ); |
|
7862 CleanupStack::PushL( cascadeMenu ); |
|
7863 cascadeMenu->AddMenuItemsL( aCascadeId, 0 ); |
|
7864 iMenuObserver->DynInitMenuPaneL( aCascadeId, cascadeMenu ); |
|
7865 |
|
7866 TInt menuItemCount( cascadeMenu->iItemArray->Count() ); |
|
7867 for ( TInt i = 0; i < menuItemCount; ++i ) |
|
7868 { |
|
7869 CEikMenuPaneItem* item = cascadeMenu->iItemArray->At( i ); |
|
7870 if ( ( aItemSpecific |
|
7871 && CEikMenuPaneExtension::ItemSpecificCommand( *item ) ) |
|
7872 || ( !aItemSpecific |
|
7873 && !( item->iData.iFlags & EEikMenuItemDimmed ) ) ) |
|
7874 { |
|
7875 aMenuData.AddMenuItemToDataArrayL( |
|
7876 item->iData.iCommandId, |
|
7877 item->iData.iCascadeId, |
|
7878 item->iData.iText ); |
|
7879 } |
|
7880 } |
|
7881 CleanupStack::PopAndDestroy( cascadeMenu ); |
|
7882 } |
|
7883 } |
|
7884 |
|
7885 |
|
7886 // ----------------------------------------------------------------------------- |
|
7887 // CEikMenuPane::SetDefaultHighlight |
|
7888 // ----------------------------------------------------------------------------- |
|
7889 // |
|
7890 void CEikMenuPane::SetDefaultHighlight() |
|
7891 { |
|
7892 if ( iExtension ) |
|
7893 { |
|
7894 iExtension->SetDefaultHighlight(); |
|
7895 } |
|
7896 } |
|
7897 |
|
7898 // end of file |
|
7899 |