|
1 /* |
|
2 * Copyright (c) 2006, 2007 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 for CAknTreeListView class. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <AknUtils.h> |
|
20 #include <skinlayout.cdl.h> |
|
21 #include <aknlayoutscalable_avkon.cdl.h> |
|
22 #include <AknsBasicBackgroundControlContext.h> |
|
23 #include <AknsDrawUtils.h> |
|
24 #include <barsread.h> |
|
25 #include <aknappui.h> |
|
26 #include <aknitemactionmenu.h> |
|
27 #include <AknTasHook.h> // for testability hooks |
|
28 #include <aknPriv.hrh> |
|
29 #include "akntreelistview.h" |
|
30 #include "akntree.h" |
|
31 #include "akntreelist.h" |
|
32 #include "akntreeiterator.h" |
|
33 #include "akntreelistphysicshandler.h" |
|
34 |
|
35 |
|
36 |
|
37 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
38 |
|
39 #include <aknlistboxtfxinternal.h> // LISTBOX EFFECTS IMPLEMENTATION |
|
40 #include <aknlistloadertfx.h> |
|
41 |
|
42 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
43 // Value selected so that enough items fit in the array with vga resolution. |
|
44 const TInt KVisibleItemsArrayGranularity = 16; |
|
45 |
|
46 // Timeout for long keypress used in markable lists. |
|
47 const TInt KLongPressInterval = 600000; // 0.6 seconds |
|
48 |
|
49 // Number of additional items to draw |
|
50 const TInt KAdditionalItems = 2; |
|
51 |
|
52 |
|
53 // Tree list view flag definitions. |
|
54 enum TAknTreeListViewFlags |
|
55 { |
|
56 EFlagStructureLines, |
|
57 EFlagIndention, |
|
58 EFlagLooping, |
|
59 EFlagUpdateBackground, |
|
60 EFlagMarkingEnabled, // Marking of list items is enabled. |
|
61 EFlagMarkingMode, // List in marking mode (MSK controlled by list). |
|
62 EFlagMark, // List items are being marked. |
|
63 EFlagUnmark, // List items are being unmarked. |
|
64 EFlagSimultaneousMarking, // Simultaneous marking ongoing. |
|
65 EFlagHashKeyPressed, |
|
66 EFlagCtrlKeyPressed, |
|
67 EFlagShiftKeyPressed, |
|
68 EFlagSaveFocusAfterSorting, |
|
69 EFlagSingleClickEnabled, |
|
70 EFlagHighlightEnabled, // Is highlight drawing enabled |
|
71 EFlagIgnoreButtonUpEvent // Up event ignored (when styluspopup menu open) |
|
72 }; |
|
73 |
|
74 |
|
75 // ======== MEMBER FUNCTIONS ======== |
|
76 |
|
77 // --------------------------------------------------------------------------- |
|
78 // Two-phased constructor. |
|
79 // --------------------------------------------------------------------------- |
|
80 // |
|
81 CAknTreeListView* CAknTreeListView::NewL( const CCoeControl& aContainer, |
|
82 CAknTree& aTree, CAknTreeList& aList ) |
|
83 { |
|
84 CAknTreeListView* self = new( ELeave ) CAknTreeListView( aTree, aList ); |
|
85 CleanupStack::PushL( self ); |
|
86 self->ConstructL( aContainer ); |
|
87 CleanupStack::Pop( self ); |
|
88 AKNTASHOOK_ADDL( self, "CAknTreeListView" ); |
|
89 return self; |
|
90 } |
|
91 |
|
92 |
|
93 // --------------------------------------------------------------------------- |
|
94 // Destructor. |
|
95 // --------------------------------------------------------------------------- |
|
96 // |
|
97 CAknTreeListView::~CAknTreeListView() |
|
98 { |
|
99 AKNTASHOOK_REMOVE(); |
|
100 AknsUtils::DeregisterControlPosition( this ); |
|
101 iItems.Close(); |
|
102 iFocusedItem = NULL; // Not owned. |
|
103 delete iEmptyListText; |
|
104 delete iScrollbarFrame; |
|
105 delete iAnimation; |
|
106 delete iLongPressTimer; |
|
107 delete iPhysicsHandler; |
|
108 |
|
109 if ( iItemActionMenu ) |
|
110 { |
|
111 iItemActionMenu->RemoveCollection( *this ); |
|
112 } |
|
113 delete iLongTapDetector; |
|
114 |
|
115 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
116 if ( CAknListLoader::TfxApiInternal( iGc ) ) |
|
117 { |
|
118 delete iGc; |
|
119 } |
|
120 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
121 } |
|
122 |
|
123 |
|
124 // --------------------------------------------------------------------------- |
|
125 // Returns the specified layout rectangle. |
|
126 // --------------------------------------------------------------------------- |
|
127 // |
|
128 TRect CAknTreeListView::RectFromLayout( const TRect& aParent, |
|
129 const TAknWindowComponentLayout& aComponentLayout ) |
|
130 { |
|
131 TAknLayoutRect layoutRect; |
|
132 layoutRect.LayoutRect( aParent, aComponentLayout.LayoutLine() ); |
|
133 return layoutRect.Rect(); |
|
134 } |
|
135 |
|
136 |
|
137 // --------------------------------------------------------------------------- |
|
138 // Sets the focused item and its position in the view. |
|
139 // --------------------------------------------------------------------------- |
|
140 // |
|
141 void CAknTreeListView::SetFocusedItem( CAknTreeItem* aItem, |
|
142 TInt aIndex, TBool aDrawNow ) |
|
143 { |
|
144 if ( FocusedItem() != aItem || FocusIndex() != aIndex ) |
|
145 { |
|
146 SetFocusedItem( aItem ); |
|
147 if ( aItem ) |
|
148 { |
|
149 UpdateVisibleItems( aIndex, aItem ); |
|
150 UpdateViewLevel(); |
|
151 if ( IsMarkable() ) |
|
152 { |
|
153 UpdateMSKCommand(); |
|
154 } |
|
155 } |
|
156 } |
|
157 |
|
158 // Updates the highlight animation, if the size or background of focused |
|
159 // item has been changed. |
|
160 UpdateAnimation(); |
|
161 |
|
162 if ( aDrawNow ) |
|
163 { |
|
164 Window().Invalidate( Rect() ); |
|
165 } |
|
166 UpdateScrollbars(); |
|
167 } |
|
168 |
|
169 |
|
170 // --------------------------------------------------------------------------- |
|
171 // Sets the focused item and its position in the view. |
|
172 // --------------------------------------------------------------------------- |
|
173 // |
|
174 void CAknTreeListView::SetFocusedItemAndView( CAknTreeItem* aItem ) |
|
175 { |
|
176 if ( FocusedItem() != aItem) |
|
177 { |
|
178 |
|
179 SetFocusedItem( aItem ); |
|
180 |
|
181 iPreviouslyFocusedItem = FocusedItem(); |
|
182 |
|
183 if ( aItem ) |
|
184 { |
|
185 TInt index = iTree.ItemIndex( aItem ); |
|
186 if ( index < iItems.Count() ) |
|
187 { |
|
188 // focused item in first page, |
|
189 // set focused item to correct line and update view |
|
190 // to the beginning of list |
|
191 UpdateVisibleItems( index, aItem ); |
|
192 } |
|
193 else |
|
194 { |
|
195 // focused item not in first page, |
|
196 // set focused item and update view so that focused item |
|
197 // is at the lowest line on the screen |
|
198 UpdateVisibleItems( iItems.Count() - 1, aItem ); |
|
199 } |
|
200 UpdateViewLevel(); |
|
201 |
|
202 if ( IsMarkable() ) |
|
203 { |
|
204 UpdateMSKCommand(); |
|
205 } |
|
206 } |
|
207 } |
|
208 |
|
209 // Updates the highlight animation, if the size or background of focused |
|
210 // item has been changed. |
|
211 UpdateAnimation(); |
|
212 |
|
213 // Draw always |
|
214 Window().Invalidate( Rect() ); |
|
215 |
|
216 UpdateScrollbars(); |
|
217 } |
|
218 |
|
219 |
|
220 |
|
221 // --------------------------------------------------------------------------- |
|
222 // |
|
223 // --------------------------------------------------------------------------- |
|
224 // |
|
225 TInt CAknTreeListView::FocusedItemIndex() const |
|
226 { |
|
227 if ( FocusedItemVisible() ) |
|
228 { |
|
229 return FocusIndex(); |
|
230 } |
|
231 return -1; |
|
232 } |
|
233 |
|
234 // --------------------------------------------------------------------------- |
|
235 // |
|
236 // --------------------------------------------------------------------------- |
|
237 // |
|
238 TInt CAknTreeListView::VisibleItemIndex( CAknTreeItem* aItem ) const |
|
239 { |
|
240 for ( TInt ii = 0; ii < iItems.Count(); ++ii ) |
|
241 { |
|
242 if ( aItem == iItems[ii].Item() ) |
|
243 { |
|
244 return ii; |
|
245 } |
|
246 } |
|
247 return -1; |
|
248 } |
|
249 |
|
250 |
|
251 |
|
252 // --------------------------------------------------------------------------- |
|
253 // |
|
254 // --------------------------------------------------------------------------- |
|
255 // |
|
256 void CAknTreeListView::SetFocusBehaviour( TBool saveFocus ) |
|
257 { |
|
258 if ( saveFocus) |
|
259 { |
|
260 iFlags.Set( EFlagSaveFocusAfterSorting ); |
|
261 } |
|
262 else |
|
263 { |
|
264 iFlags.Clear( EFlagSaveFocusAfterSorting ); |
|
265 } |
|
266 } |
|
267 |
|
268 |
|
269 // --------------------------------------------------------------------------- |
|
270 // Returns pointer to the focused item. |
|
271 // --------------------------------------------------------------------------- |
|
272 // |
|
273 CAknTreeItem* CAknTreeListView::FocusedItem() const |
|
274 { |
|
275 return iFocusedItem; |
|
276 } |
|
277 |
|
278 |
|
279 // --------------------------------------------------------------------------- |
|
280 // Returns the highlight rectangle for the focused item. |
|
281 // --------------------------------------------------------------------------- |
|
282 // |
|
283 TRect CAknTreeListView::HighlightRect() const |
|
284 { |
|
285 if ( IsFocused() && FocusedItemVisible() ) |
|
286 { |
|
287 TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, |
|
288 Indention(), IndentionWidth() ); |
|
289 |
|
290 TPoint position; |
|
291 if ( AknsUtils::GetControlPosition( this, position ) != KErrNone ) |
|
292 { |
|
293 position = PositionRelativeToScreen(); |
|
294 } |
|
295 |
|
296 rect.Move( position ); |
|
297 return rect; |
|
298 } |
|
299 else |
|
300 { |
|
301 return TRect(); |
|
302 } |
|
303 } |
|
304 |
|
305 |
|
306 // --------------------------------------------------------------------------- |
|
307 // Returns whether the list is set looping. |
|
308 // --------------------------------------------------------------------------- |
|
309 // |
|
310 TBool CAknTreeListView::IsLooping() const |
|
311 { |
|
312 return iFlags.IsSet( EFlagLooping ); |
|
313 } |
|
314 |
|
315 |
|
316 // --------------------------------------------------------------------------- |
|
317 // Sets the list to looping or non-looping mode. |
|
318 // --------------------------------------------------------------------------- |
|
319 // |
|
320 void CAknTreeListView::SetLooping( TBool aLooping ) |
|
321 { |
|
322 iFlags.Assign( EFlagLooping, aLooping ); |
|
323 } |
|
324 |
|
325 |
|
326 // --------------------------------------------------------------------------- |
|
327 // Returns whether the structure lines are set visible. |
|
328 // --------------------------------------------------------------------------- |
|
329 // |
|
330 TBool CAknTreeListView::StructureLines() const |
|
331 { |
|
332 return iFlags.IsSet( EFlagStructureLines ) && |
|
333 iFlags.IsSet( EFlagIndention ); |
|
334 } |
|
335 |
|
336 |
|
337 // --------------------------------------------------------------------------- |
|
338 // Sets the visibility of structure lines. |
|
339 // --------------------------------------------------------------------------- |
|
340 // |
|
341 void CAknTreeListView::SetStructureLineVisibility( TBool aVisible ) |
|
342 { |
|
343 iFlags.Assign( EFlagStructureLines, aVisible ); |
|
344 Window().Invalidate( Rect() ); |
|
345 } |
|
346 |
|
347 |
|
348 // --------------------------------------------------------------------------- |
|
349 // Checks whether indention is enabled. |
|
350 // --------------------------------------------------------------------------- |
|
351 // |
|
352 TBool CAknTreeListView::Indention() const |
|
353 { |
|
354 return iFlags.IsSet( EFlagIndention ); |
|
355 } |
|
356 |
|
357 |
|
358 // --------------------------------------------------------------------------- |
|
359 // Enables or disables indention of list items. |
|
360 // --------------------------------------------------------------------------- |
|
361 // |
|
362 void CAknTreeListView::EnableIndention( TBool aEnable ) |
|
363 { |
|
364 iFlags.Assign( EFlagIndention, aEnable ); |
|
365 iMaxViewLevel = aEnable ? iTree.Depth() - 1 : 0; |
|
366 Window().Invalidate( Rect() ); |
|
367 } |
|
368 |
|
369 |
|
370 // --------------------------------------------------------------------------- |
|
371 // Returns the width of single indention step. |
|
372 // --------------------------------------------------------------------------- |
|
373 // |
|
374 TInt CAknTreeListView::IndentionWidth() const |
|
375 { |
|
376 if ( StructureLines() ) |
|
377 { |
|
378 return -1; |
|
379 } |
|
380 else |
|
381 { |
|
382 return iIndentionWidth; |
|
383 } |
|
384 } |
|
385 |
|
386 |
|
387 // --------------------------------------------------------------------------- |
|
388 // Sets the width of one indention step. |
|
389 // --------------------------------------------------------------------------- |
|
390 // |
|
391 void CAknTreeListView::SetIndentionWidth( TInt aIndentionWidth ) |
|
392 { |
|
393 iIndentionWidth = aIndentionWidth; |
|
394 } |
|
395 |
|
396 |
|
397 // --------------------------------------------------------------------------- |
|
398 // Checks whether marking is enabled. |
|
399 // --------------------------------------------------------------------------- |
|
400 // |
|
401 TBool CAknTreeListView::IsMarkable() const |
|
402 { |
|
403 return iFlags.IsSet( EFlagMarkingEnabled ); |
|
404 } |
|
405 |
|
406 |
|
407 // --------------------------------------------------------------------------- |
|
408 // Enables or disables the marking of list items. |
|
409 // --------------------------------------------------------------------------- |
|
410 // |
|
411 void CAknTreeListView::EnableMarking( TBool aEnable ) |
|
412 { |
|
413 iFlags.Assign( EFlagMarkingEnabled, aEnable ); |
|
414 } |
|
415 |
|
416 // --------------------------------------------------------------------------- |
|
417 // Sets text for the empty list. |
|
418 // --------------------------------------------------------------------------- |
|
419 // |
|
420 void CAknTreeListView::SetEmptyTextL(const TDesC& aText) |
|
421 { |
|
422 delete iEmptyListText; |
|
423 iEmptyListText = NULL; |
|
424 iEmptyListText = aText.AllocL(); |
|
425 UpdateScrollbars(); |
|
426 } |
|
427 |
|
428 |
|
429 // --------------------------------------------------------------------------- |
|
430 // InitPhysicsL |
|
431 // --------------------------------------------------------------------------- |
|
432 // |
|
433 void CAknTreeListView::InitPhysicsL() |
|
434 { |
|
435 if ( iPhysicsHandler ) |
|
436 { |
|
437 iPhysicsHandler->InitPhysicsL(); |
|
438 } |
|
439 } |
|
440 |
|
441 |
|
442 // --------------------------------------------------------------------------- |
|
443 // SetHighlight |
|
444 // --------------------------------------------------------------------------- |
|
445 // |
|
446 void CAknTreeListView::SetHighlight( CAknTreeItem* aItemToBeFocused, |
|
447 const TInt& aIndexToBeFocused ) |
|
448 { |
|
449 if ( aItemToBeFocused ) |
|
450 { |
|
451 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
452 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
453 |
|
454 if ( transApi && !transApi->EffectsDisabled() && !aItemToBeFocused->Node() ) |
|
455 { |
|
456 transApi->SetMoveType( MAknListBoxTfxInternal::EListTap ); |
|
457 } |
|
458 #endif |
|
459 |
|
460 SetFocusedItem( aItemToBeFocused, aIndexToBeFocused, ETrue ); |
|
461 iPreviouslyFocusedItem = aItemToBeFocused; |
|
462 } |
|
463 } |
|
464 |
|
465 |
|
466 // --------------------------------------------------------------------------- |
|
467 // SelectItem |
|
468 // --------------------------------------------------------------------------- |
|
469 // |
|
470 void CAknTreeListView::SelectItem( CAknTreeItem* aSelectedItem ) |
|
471 { |
|
472 SelectItem( aSelectedItem, EFalse ); |
|
473 } |
|
474 |
|
475 |
|
476 // --------------------------------------------------------------------------- |
|
477 // VisibleItemCount |
|
478 // --------------------------------------------------------------------------- |
|
479 // |
|
480 TInt CAknTreeListView::VisibleItemCount() const |
|
481 { |
|
482 TInt count( iItems.Count() ); |
|
483 count += KAdditionalItems; |
|
484 return count; |
|
485 } |
|
486 |
|
487 |
|
488 // --------------------------------------------------------------------------- |
|
489 // SetPressedDownState |
|
490 // --------------------------------------------------------------------------- |
|
491 // |
|
492 void CAknTreeListView::SetPressedDownState( const TBool& aPressedDown ) |
|
493 { |
|
494 iIsPressedDownState = aPressedDown; |
|
495 } |
|
496 |
|
497 |
|
498 // --------------------------------------------------------------------------- |
|
499 // UpdateTreeListView |
|
500 // --------------------------------------------------------------------------- |
|
501 // |
|
502 void CAknTreeListView::UpdateTreeListView( const TInt& aFirstItem, |
|
503 const TBool& aDrawNow ) |
|
504 { |
|
505 CAknTreeItem* first = iTree.VisibleItem( aFirstItem ); |
|
506 UpdateVisibleItems( 0, first ); |
|
507 UpdateScrollbars(); |
|
508 UpdateAnimation(); |
|
509 |
|
510 if ( aDrawNow ) |
|
511 { |
|
512 DrawNow(); |
|
513 } |
|
514 else |
|
515 { |
|
516 Window().Invalidate( Rect() ); |
|
517 } |
|
518 } |
|
519 |
|
520 |
|
521 // --------------------------------------------------------------------------- |
|
522 // Offset |
|
523 // --------------------------------------------------------------------------- |
|
524 // |
|
525 TInt CAknTreeListView::Offset() const |
|
526 { |
|
527 return iPhysicsHandler->Offset(); |
|
528 } |
|
529 |
|
530 |
|
531 // --------------------------------------------------------------------------- |
|
532 // From class CCoeControl. |
|
533 // Handles key events. |
|
534 // --------------------------------------------------------------------------- |
|
535 // |
|
536 TKeyResponse CAknTreeListView::OfferKeyEventL( const TKeyEvent& aKeyEvent, |
|
537 TEventCode aType ) |
|
538 { |
|
539 TKeyResponse response = EKeyWasNotConsumed; |
|
540 if ( aType == EEventKey ) |
|
541 { |
|
542 response = EKeyWasConsumed; |
|
543 |
|
544 // In single click mode first key press enables highlight |
|
545 if ( SingleClickEnabled() && !HighlightEnabled() ) |
|
546 { |
|
547 if ( ( aKeyEvent.iCode == EKeyUpArrow || |
|
548 aKeyEvent.iCode == EKeyDownArrow || |
|
549 aKeyEvent.iCode == EKeyEnter || |
|
550 aKeyEvent.iCode == EKeyOK ) && iItems.Count() ) |
|
551 { |
|
552 TInt index = FirstVisibleItemIndex(); |
|
553 EnableHighlight( ETrue ); |
|
554 // Check if marquee needs to be enabled |
|
555 if ( iList.Flags() & KAknTreeListMarqueeScrolling ) |
|
556 { |
|
557 iTree.EnableMarquee( ETrue ); |
|
558 } |
|
559 if ( iPhysicsHandler->Offset() == 0 ) |
|
560 { |
|
561 SetFocusedItem( iItems[0].Item(), index, ETrue ); |
|
562 } |
|
563 else |
|
564 { |
|
565 SetFocusedItem( iItems[0].Item(), index, EFalse ); |
|
566 HandleDownArrowKeyEvent(); |
|
567 } |
|
568 return EKeyWasConsumed; |
|
569 } |
|
570 } |
|
571 |
|
572 switch ( aKeyEvent.iCode ) |
|
573 { |
|
574 case EKeyLeftArrow: |
|
575 { |
|
576 HandleLeftArrowKeyEvent(); |
|
577 break; |
|
578 } |
|
579 case EKeyRightArrow: |
|
580 { |
|
581 HandleRightArrowKeyEvent(); |
|
582 break; |
|
583 } |
|
584 case EKeyUpArrow: |
|
585 { |
|
586 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
587 // LISTBOX EFFECTS IMPLEMENTATION |
|
588 // |
|
589 // Set type of momement |
|
590 // |
|
591 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
592 if ( transApi ) |
|
593 { |
|
594 transApi->SetMoveType( MAknListBoxTfxInternal::EListMoveUp ); |
|
595 } |
|
596 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
597 |
|
598 HandleUpArrowKeyEvent(); |
|
599 break; |
|
600 } |
|
601 case EKeyDownArrow: |
|
602 { |
|
603 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
604 // LISTBOX EFFECTS IMPLEMENTATION |
|
605 // |
|
606 // Set type of momement |
|
607 // |
|
608 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
609 if ( transApi ) |
|
610 { |
|
611 transApi->SetMoveType( MAknListBoxTfxInternal::EListMoveDown ); |
|
612 } |
|
613 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
614 HandleDownArrowKeyEvent(); |
|
615 break; |
|
616 } |
|
617 case EKeyEnter: // fall-through intended here |
|
618 case EKeyOK: |
|
619 { |
|
620 // Ignore repeated events. |
|
621 if ( aKeyEvent.iRepeats == 0 ) |
|
622 { |
|
623 HandleSelectionKeyEvent(); |
|
624 } |
|
625 break; |
|
626 } |
|
627 default: |
|
628 response = EKeyWasNotConsumed; |
|
629 break; |
|
630 } |
|
631 } |
|
632 |
|
633 else if ( aType == EEventKeyDown ) |
|
634 { |
|
635 if ( aKeyEvent.iScanCode == EStdKeyLeftShift || |
|
636 aKeyEvent.iScanCode == EStdKeyRightShift ) |
|
637 { |
|
638 iFlags.Set( EFlagShiftKeyPressed ); |
|
639 if ( !MarkingOngoing() ) |
|
640 { |
|
641 BeginMarkingL(); |
|
642 } |
|
643 response = EKeyWasConsumed; |
|
644 } |
|
645 |
|
646 else if ( aKeyEvent.iScanCode == EStdKeyLeftCtrl || |
|
647 aKeyEvent.iScanCode == EStdKeyRightCtrl ) |
|
648 { |
|
649 iFlags.Set( EFlagCtrlKeyPressed ); |
|
650 if ( !MarkingOngoing() ) |
|
651 { |
|
652 BeginMarkingL(); |
|
653 } |
|
654 response = EKeyWasConsumed; |
|
655 } |
|
656 |
|
657 else if ( aKeyEvent.iScanCode == EStdKeyHash ) |
|
658 { |
|
659 iFlags.Set( EFlagHashKeyPressed ); |
|
660 if ( !MarkingOngoing() ) |
|
661 { |
|
662 BeginMarkingL(); |
|
663 } |
|
664 response = EKeyWasConsumed; |
|
665 } |
|
666 } |
|
667 |
|
668 else if ( aType == EEventKeyUp ) |
|
669 { |
|
670 const TInt KShiftModifiers = |
|
671 EModifierLeftShift | EModifierRightShift | EModifierShift; |
|
672 |
|
673 const TInt KCtrlModifiers = |
|
674 EModifierLeftCtrl | EModifierRightCtrl | EModifierCtrl; |
|
675 |
|
676 if ( aKeyEvent.iScanCode == EStdKeyLeftCtrl || |
|
677 aKeyEvent.iScanCode == EStdKeyRightCtrl || |
|
678 aKeyEvent.iScanCode == EStdKeyLeftShift || |
|
679 aKeyEvent.iScanCode == EStdKeyRightShift ) |
|
680 { |
|
681 if ( !( aKeyEvent.iModifiers & KShiftModifiers ) ) |
|
682 { |
|
683 iFlags.Clear( EFlagShiftKeyPressed ); |
|
684 } |
|
685 |
|
686 if ( !( aKeyEvent.iModifiers & KCtrlModifiers ) ) |
|
687 { |
|
688 iFlags.Clear( EFlagCtrlKeyPressed ); |
|
689 } |
|
690 |
|
691 if ( iFlags.IsClear( EFlagShiftKeyPressed ) && |
|
692 iFlags.IsClear( EFlagCtrlKeyPressed ) && |
|
693 iFlags.IsClear( EFlagHashKeyPressed ) && |
|
694 MarkingOngoing() ) |
|
695 { |
|
696 EndMarking(); |
|
697 } |
|
698 response = EKeyWasConsumed; |
|
699 } |
|
700 |
|
701 else if ( aKeyEvent.iScanCode == EStdKeyHash ) |
|
702 { |
|
703 iFlags.Clear( EFlagHashKeyPressed ); |
|
704 |
|
705 if ( iFlags.IsClear( EFlagShiftKeyPressed ) && |
|
706 iFlags.IsClear( EFlagCtrlKeyPressed ) ) |
|
707 { |
|
708 if ( iFlags.IsClear( EFlagSimultaneousMarking ) ) |
|
709 { |
|
710 // Item marking is changed when several items have not |
|
711 // been marked by moving focus while pressing hash key. |
|
712 if ( FocusedItem() ) |
|
713 { |
|
714 MarkItem( FocusedItem(), !FocusedItem()->IsMarked(), |
|
715 ETrue ); |
|
716 } |
|
717 } |
|
718 |
|
719 if ( MarkingOngoing() ) |
|
720 { |
|
721 EndMarking(); |
|
722 } |
|
723 } |
|
724 response = EKeyWasConsumed; |
|
725 } |
|
726 } |
|
727 |
|
728 if ( aType == EEventKey ) |
|
729 { |
|
730 // Check if view offset needs to be restored |
|
731 iPhysicsHandler->HandleKeyEvent( aKeyEvent.iCode ); |
|
732 } |
|
733 |
|
734 return response; |
|
735 } |
|
736 |
|
737 |
|
738 // --------------------------------------------------------------------------- |
|
739 // Changes the visibility of the view. |
|
740 // --------------------------------------------------------------------------- |
|
741 // |
|
742 void CAknTreeListView::MakeVisible( TBool aVisible ) |
|
743 { |
|
744 CAknControl::MakeVisible( aVisible ); |
|
745 |
|
746 if ( aVisible ) |
|
747 { |
|
748 UpdateScrollbars(); |
|
749 } |
|
750 } |
|
751 |
|
752 |
|
753 // --------------------------------------------------------------------------- |
|
754 // From class CCoeControl. |
|
755 // Sets the control's containing window by copying it from aContainer. |
|
756 // Method also reconstructs the scrollbars for the view. Otherwise, they would |
|
757 // still be using the previously set, possibly deleted container window. |
|
758 // --------------------------------------------------------------------------- |
|
759 // |
|
760 void CAknTreeListView::SetContainerWindowL( const CCoeControl& aContainer ) |
|
761 { |
|
762 if ( iScrollbarFrame ) |
|
763 { |
|
764 delete iScrollbarFrame; |
|
765 iScrollbarFrame = NULL; |
|
766 } |
|
767 |
|
768 CAknControl::SetContainerWindowL( aContainer ); |
|
769 |
|
770 Window().SetPointerGrab( ETrue ); |
|
771 |
|
772 iScrollbarFrame = new ( ELeave ) CEikScrollBarFrame( this, this ); |
|
773 iScrollbarFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse ); |
|
774 } |
|
775 |
|
776 |
|
777 // --------------------------------------------------------------------------- |
|
778 // From class CCoeControl. |
|
779 // Handles changes in resources. |
|
780 // --------------------------------------------------------------------------- |
|
781 // |
|
782 void CAknTreeListView::HandleResourceChange( TInt aType ) |
|
783 { |
|
784 CAknControl::HandleResourceChange( aType ); |
|
785 if ( aType == KAknsMessageSkinChange ) |
|
786 { |
|
787 TRAPD( error, CreateAnimationL() ) |
|
788 if ( error ) |
|
789 { |
|
790 delete iAnimation; |
|
791 iAnimation = NULL; |
|
792 } |
|
793 } |
|
794 else if ( aType == KEikDynamicLayoutVariantSwitch && FocusedItem() ) |
|
795 { |
|
796 if ( !FocusedItemVisible() ) |
|
797 { |
|
798 TInt firstItemIndex = 0; |
|
799 if ( iItems.Count() && iItems[0].Item() ) |
|
800 { |
|
801 firstItemIndex = iTree.VisibleItemIndex( iItems[0].Item() ); |
|
802 } |
|
803 |
|
804 TInt index = 0; |
|
805 if ( firstItemIndex < iTree.VisibleItemIndex( FocusedItem() ) ) |
|
806 { |
|
807 index = iItems.Count() - 1; |
|
808 } |
|
809 |
|
810 SetFocusedItem( FocusedItem(), index, ETrue ); |
|
811 } |
|
812 else |
|
813 { |
|
814 SetFocusedItem( FocusedItem(), FocusIndex(), ETrue ); |
|
815 |
|
816 |
|
817 // This block moves visible view after layout switch |
|
818 // if there are not enough items to fill whole screen |
|
819 TInt visibleItemIndex = iTree.VisibleItemIndex( FocusedItem() ); |
|
820 if ( visibleItemIndex != KErrNotFound) |
|
821 { |
|
822 TInt focusedItemIndex = FocusedItemIndex(); |
|
823 if (focusedItemIndex != -1) |
|
824 { |
|
825 TInt height = iTree.VisibleItemCount() - visibleItemIndex + focusedItemIndex; |
|
826 TInt itemCountLimit = iItems.Count(); |
|
827 |
|
828 if ( height < itemCountLimit && height < iTree.VisibleItemCount() ) |
|
829 { |
|
830 TInt move = itemCountLimit - height; |
|
831 UpdateVisibleItems( focusedItemIndex + move, FocusedItem() ); |
|
832 } |
|
833 } |
|
834 } |
|
835 // end of block |
|
836 } |
|
837 } |
|
838 else if ( aType == KAknMessageFocusLost && HighlightEnabled() ) |
|
839 { |
|
840 EnableHighlight( EFalse ); |
|
841 } |
|
842 } |
|
843 |
|
844 |
|
845 // --------------------------------------------------------------------------- |
|
846 // From class CCoeControl. |
|
847 // Handles pointer events. Moves the focus on stylus down events to the |
|
848 // pointed item, and selects the item on stylus up event if the pointed item |
|
849 // is the same as on stylus down event. Otherwise, the pointed item is set |
|
850 // focused. |
|
851 // --------------------------------------------------------------------------- |
|
852 // |
|
853 void CAknTreeListView::HandlePointerEventL( const TPointerEvent& aPointerEvent ) |
|
854 { |
|
855 if ( iFlags.IsSet( EFlagIgnoreButtonUpEvent ) |
|
856 && aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
857 { |
|
858 return; |
|
859 } |
|
860 |
|
861 if ( GrabbingComponent() != NULL ) |
|
862 { |
|
863 iPhysicsHandler->ResetEventBlockingStatus(); |
|
864 } |
|
865 else |
|
866 { |
|
867 if( aPointerEvent.iType == TPointerEvent::EButton1Down ) |
|
868 { |
|
869 iPreviouslyFocusedItem = FocusedItem(); |
|
870 } |
|
871 |
|
872 iPhysicsHandler->HandlePointerEventL( aPointerEvent, iViewLevel, |
|
873 MarkingOngoing(), iFlags.IsSet( EFlagShiftKeyPressed ), |
|
874 iFlags.IsSet( EFlagCtrlKeyPressed ) ); |
|
875 } |
|
876 CAknControl::HandlePointerEventL( aPointerEvent ); |
|
877 } |
|
878 |
|
879 |
|
880 // --------------------------------------------------------------------------- |
|
881 // From class CCoeControl. |
|
882 // --------------------------------------------------------------------------- |
|
883 // |
|
884 TInt CAknTreeListView::CountComponentControls() const |
|
885 { |
|
886 return iScrollbarFrame ? iScrollbarFrame->CountComponentControls() : NULL; |
|
887 } |
|
888 |
|
889 |
|
890 // --------------------------------------------------------------------------- |
|
891 // From class CCoeControl. |
|
892 // --------------------------------------------------------------------------- |
|
893 // |
|
894 CCoeControl* CAknTreeListView::ComponentControl( TInt aIndex ) const |
|
895 { |
|
896 return iScrollbarFrame ? iScrollbarFrame->ComponentControl( aIndex ) : NULL; |
|
897 } |
|
898 |
|
899 |
|
900 // --------------------------------------------------------------------------- |
|
901 // From class MEikScrollBarObserver. |
|
902 // --------------------------------------------------------------------------- |
|
903 // |
|
904 void CAknTreeListView::HandleScrollEventL( CEikScrollBar* aScrollBar, |
|
905 TEikScrollEvent aEventType ) |
|
906 { |
|
907 __ASSERT_DEBUG( aScrollBar, User::Invariant() ); |
|
908 __ASSERT_DEBUG( iScrollbarFrame, User::Invariant() ); |
|
909 |
|
910 if ( SingleClickEnabled() ) |
|
911 { |
|
912 EnableHighlight( EFalse ); |
|
913 } |
|
914 |
|
915 TInt thumbPosition = aScrollBar->ThumbPosition(); |
|
916 if ( AknLayoutUtils::LayoutMirrored() && |
|
917 aScrollBar != iScrollbarFrame->VerticalScrollBar() ) |
|
918 { |
|
919 const TEikScrollBarModel* model = aScrollBar->Model(); |
|
920 thumbPosition = ( model->iScrollSpan - model->iThumbSpan ) |
|
921 - thumbPosition; |
|
922 } |
|
923 |
|
924 switch ( aEventType ) |
|
925 { |
|
926 case EEikScrollThumbReleaseVert: |
|
927 // Ignored. |
|
928 break; |
|
929 |
|
930 case EEikScrollLeft: |
|
931 case EEikScrollRight: |
|
932 case EEikScrollPageLeft: |
|
933 case EEikScrollPageRight: |
|
934 iViewLevel = thumbPosition; |
|
935 UpdateScrollbars(); |
|
936 UpdateAnimation(); |
|
937 Window().Invalidate( Rect() ); |
|
938 break; |
|
939 |
|
940 case EEikScrollThumbDragHoriz: |
|
941 iViewLevel = thumbPosition; |
|
942 UpdateAnimation(); |
|
943 Window().Invalidate( Rect() ); |
|
944 break; |
|
945 |
|
946 case EEikScrollThumbReleaseHoriz: |
|
947 UpdateScrollbars(); |
|
948 break; |
|
949 |
|
950 case EEikScrollHome: |
|
951 // Not in use! |
|
952 break; |
|
953 |
|
954 case EEikScrollEnd: |
|
955 // Not in use! |
|
956 break; |
|
957 |
|
958 default: |
|
959 break; |
|
960 } |
|
961 |
|
962 iPhysicsHandler->HandleScrollEventL( aEventType, thumbPosition ); |
|
963 } |
|
964 |
|
965 |
|
966 // --------------------------------------------------------------------------- |
|
967 // From class MAknTreeObserver. |
|
968 // Handles tree events. |
|
969 // --------------------------------------------------------------------------- |
|
970 // |
|
971 void CAknTreeListView::HandleTreeEvent( TEvent aEvent, CAknTreeItem* aItem, |
|
972 TBool aDrawNow ) |
|
973 { |
|
974 |
|
975 // Note: max view level is needed only for scrollbar updating |
|
976 |
|
977 if ( Indention() ) |
|
978 { |
|
979 switch ( aEvent ) |
|
980 { |
|
981 case EItemAdded: |
|
982 case EItemRemoveBegin: |
|
983 case EItemRemoveEnd: |
|
984 { |
|
985 if ( aDrawNow ) |
|
986 { |
|
987 iMaxViewLevel = iTree.Depth() - 1; |
|
988 } |
|
989 break; |
|
990 } |
|
991 |
|
992 case EItemMoved: |
|
993 case ENodeExpanded: |
|
994 case ENodeCollapsed: |
|
995 case ETreeSorted: |
|
996 { |
|
997 iMaxViewLevel = iTree.Depth() - 1; |
|
998 break; |
|
999 } |
|
1000 |
|
1001 case EItemModified: |
|
1002 break; |
|
1003 |
|
1004 default: |
|
1005 break; |
|
1006 } |
|
1007 } |
|
1008 |
|
1009 switch ( aEvent ) |
|
1010 { |
|
1011 case EItemAdded: |
|
1012 HandleItemAddedEvent( aItem, aDrawNow ); |
|
1013 TRAP_IGNORE( InitPhysicsL() ); |
|
1014 break; |
|
1015 |
|
1016 case EItemMoved: |
|
1017 HandleItemMovedEvent( aItem ); |
|
1018 TRAP_IGNORE( InitPhysicsL() ); |
|
1019 break; |
|
1020 |
|
1021 case EItemRemoveBegin: |
|
1022 PrepareForItemRemoval( aItem, aDrawNow ); |
|
1023 break; |
|
1024 |
|
1025 case EItemRemoveEnd: |
|
1026 HandleItemRemovedEvent( aItem, aDrawNow ); |
|
1027 TRAP_IGNORE( InitPhysicsL() ); |
|
1028 break; |
|
1029 |
|
1030 case ENodeExpanded: |
|
1031 HandleNodeExpandedEvent( aItem->Node() ); |
|
1032 TRAP_IGNORE( InitPhysicsL() ); |
|
1033 break; |
|
1034 |
|
1035 case ENodeCollapsed: |
|
1036 HandleNodeCollapsedEvent( aItem->Node() ); |
|
1037 TRAP_IGNORE( InitPhysicsL() ); |
|
1038 break; |
|
1039 |
|
1040 case EItemModified: |
|
1041 HandleItemModifiedEvent( aItem ); |
|
1042 break; |
|
1043 |
|
1044 case ETreeSorted: |
|
1045 HandleTreeSortedEvent( aDrawNow ); |
|
1046 break; |
|
1047 |
|
1048 default: |
|
1049 break; |
|
1050 } |
|
1051 |
|
1052 if ( aDrawNow ) |
|
1053 { |
|
1054 // it should be DrawNow() here for fixing bug JLAI-7UE9RN |
|
1055 DrawNow(); |
|
1056 //Window().Invalidate( Rect() ); |
|
1057 } |
|
1058 } |
|
1059 |
|
1060 |
|
1061 // --------------------------------------------------------------------------- |
|
1062 // From class MAknsEffectAnimObserver. |
|
1063 // --------------------------------------------------------------------------- |
|
1064 // |
|
1065 void CAknTreeListView::AnimFrameReady( TInt aError, TInt /*aAnimId*/ ) |
|
1066 { |
|
1067 __ASSERT_DEBUG( iAnimation, User::Invariant() ); |
|
1068 |
|
1069 if ( aError ) |
|
1070 { |
|
1071 delete iAnimation; |
|
1072 iAnimation = NULL; |
|
1073 } |
|
1074 else if ( IsFocused() && FocusedItemVisible() ) |
|
1075 { |
|
1076 DrawNow( iItems[FocusIndex()].Rect() ); |
|
1077 } |
|
1078 else |
|
1079 { |
|
1080 iAnimation->Stop(); |
|
1081 } |
|
1082 } |
|
1083 |
|
1084 |
|
1085 // --------------------------------------------------------------------------- |
|
1086 // From class MEikCommandObserver. |
|
1087 // --------------------------------------------------------------------------- |
|
1088 // |
|
1089 void CAknTreeListView::ProcessCommandL( TInt /*aCommandId*/ ) |
|
1090 { |
|
1091 // Any event coming from MSK changes the marking of currently focused |
|
1092 // item, as MSK is being observed only when shift is pressed. |
|
1093 if ( MarkingOngoing() && FocusedItem() ) |
|
1094 { |
|
1095 MarkItem( FocusedItem(), !FocusedItem()->IsMarked(), ETrue ); |
|
1096 } |
|
1097 } |
|
1098 |
|
1099 // --------------------------------------------------------------------------- |
|
1100 // CAknTreeListView::ReportTreeListEvent |
|
1101 // --------------------------------------------------------------------------- |
|
1102 // |
|
1103 void CAknTreeListView::ReportTreeListEvent( |
|
1104 MAknTreeListObserver::TEvent aEvent, TAknTreeItemID aItem ) |
|
1105 { |
|
1106 iList.NotifyObservers( aEvent, aItem ); |
|
1107 } |
|
1108 |
|
1109 |
|
1110 // --------------------------------------------------------------------------- |
|
1111 // From class CCoeControl. |
|
1112 // Handles focus change. |
|
1113 // --------------------------------------------------------------------------- |
|
1114 // |
|
1115 void CAknTreeListView::FocusChanged( TDrawNow aDrawNow ) |
|
1116 { |
|
1117 if ( iAnimation ) |
|
1118 { |
|
1119 if ( IsFocused() ) |
|
1120 { |
|
1121 iAnimation->Start(); |
|
1122 } |
|
1123 else |
|
1124 { |
|
1125 iAnimation->Stop(); |
|
1126 } |
|
1127 } |
|
1128 |
|
1129 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1130 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
1131 if ( aDrawNow || (transApi && !transApi->EffectsDisabled()) ) |
|
1132 #else |
|
1133 if (aDrawNow) |
|
1134 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
1135 { |
|
1136 Window().Invalidate( Rect() ); |
|
1137 } |
|
1138 else if ( IsFocused() && FocusedItemVisible() ) |
|
1139 { |
|
1140 TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, Indention(), IndentionWidth() ); |
|
1141 Window().Invalidate( rect ); |
|
1142 } |
|
1143 |
|
1144 ReportTreeListEvent( MAknTreeListObserver::EItemFocused, |
|
1145 iTree.Id( FocusedItem() ) ); |
|
1146 } |
|
1147 |
|
1148 |
|
1149 // --------------------------------------------------------------------------- |
|
1150 // From class CCoeControl. |
|
1151 // Responds to changes to the size and position of this control. |
|
1152 // --------------------------------------------------------------------------- |
|
1153 // |
|
1154 void CAknTreeListView::SizeChanged() |
|
1155 { |
|
1156 // Get layout for the view. |
|
1157 LayoutView(); |
|
1158 |
|
1159 // Update scrollbars. |
|
1160 UpdateScrollbars(); |
|
1161 |
|
1162 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1163 UpdateIndexes(); |
|
1164 #endif |
|
1165 AknsUtils::RegisterControlPosition( this, PositionRelativeToScreen() ); |
|
1166 |
|
1167 TRAP_IGNORE( InitPhysicsL() ); |
|
1168 } |
|
1169 |
|
1170 |
|
1171 // --------------------------------------------------------------------------- |
|
1172 // From class CCoeControl. |
|
1173 // Responds to changes in the position of a control. |
|
1174 // --------------------------------------------------------------------------- |
|
1175 // |
|
1176 void CAknTreeListView::PositionChanged() |
|
1177 { |
|
1178 AknsUtils::RegisterControlPosition( this, PositionRelativeToScreen() ); |
|
1179 } |
|
1180 |
|
1181 |
|
1182 // --------------------------------------------------------------------------- |
|
1183 // From class CCoeControl. |
|
1184 // Retrieves an object of the same type as that encapsulated in aId. |
|
1185 // --------------------------------------------------------------------------- |
|
1186 // |
|
1187 TTypeUid::Ptr CAknTreeListView::MopSupplyObject( TTypeUid aId ) |
|
1188 { |
|
1189 return CAknControl::MopSupplyObject( aId ); |
|
1190 } |
|
1191 |
|
1192 |
|
1193 // --------------------------------------------------------------------------- |
|
1194 // C++ constructor. |
|
1195 // --------------------------------------------------------------------------- |
|
1196 // |
|
1197 CAknTreeListView::CAknTreeListView( CAknTree& aTree, CAknTreeList& aList ) |
|
1198 : iTree( aTree ), |
|
1199 iList( aList ), |
|
1200 iItems( KVisibleItemsArrayGranularity ), |
|
1201 iViewLevel( 0 ), |
|
1202 iMaxViewLevel( 0 ), |
|
1203 iStylusDownItemIndex( -1 ), |
|
1204 iAnimationIID( KAknsIIDQsnAnimList ), |
|
1205 iIndentionWidth( -1 ), |
|
1206 iPhysicsHandler( NULL ), |
|
1207 iScrollPhysicsTop( ETrue ) |
|
1208 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1209 ,iGc(NULL) |
|
1210 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
1211 ,iItemActionMenu( NULL ), |
|
1212 iLongTapDetector( NULL ) |
|
1213 { |
|
1214 if ( static_cast<CAknAppUi*>( |
|
1215 iCoeEnv->AppUi() )->IsSingleClickCompatible() ) |
|
1216 { |
|
1217 iFlags.Set( EFlagSingleClickEnabled ); |
|
1218 } |
|
1219 |
|
1220 iFlags.Set( EFlagStructureLines ); |
|
1221 iFlags.Set( EFlagIndention ); |
|
1222 } |
|
1223 |
|
1224 |
|
1225 // --------------------------------------------------------------------------- |
|
1226 // Second phase constructor. |
|
1227 // --------------------------------------------------------------------------- |
|
1228 // |
|
1229 void CAknTreeListView::ConstructL( const CCoeControl& aContainer ) |
|
1230 { |
|
1231 // Get the empty list text from resources. |
|
1232 TResourceReader reader; |
|
1233 CEikonEnv::Static()->CreateResourceReaderLC( reader, |
|
1234 R_AVKON_LISTBOX_DEFAULT_EMPTY_TEXT ); |
|
1235 iEmptyListText = reader.ReadHBufCL(); |
|
1236 CleanupStack::PopAndDestroy(); // reader |
|
1237 |
|
1238 // Setting container window also constructs scrollbars for the view. |
|
1239 SetContainerWindowL( aContainer ); |
|
1240 |
|
1241 // Construct highlight animation for the view. |
|
1242 TRAPD( error, CreateAnimationL() ) |
|
1243 if ( error ) |
|
1244 { |
|
1245 delete iAnimation; |
|
1246 iAnimation = NULL; |
|
1247 } |
|
1248 |
|
1249 // Long press timer for markable list. |
|
1250 iLongPressTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
1251 |
|
1252 if ( !iPhysicsHandler ) |
|
1253 { |
|
1254 iPhysicsHandler = CAknTreeListPhysicsHandler::NewL( this, |
|
1255 &iTree, |
|
1256 &iItems ); |
|
1257 } |
|
1258 |
|
1259 iIsPressedDownState = EFalse; |
|
1260 iIsDragged = EFalse; |
|
1261 iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this ); |
|
1262 if ( iItemActionMenu ) |
|
1263 { |
|
1264 iLongTapDetector = CAknLongTapDetector::NewL( this ); |
|
1265 } |
|
1266 |
|
1267 if ( SingleClickEnabled() ) |
|
1268 { |
|
1269 EnableHighlight( EFalse ); |
|
1270 } |
|
1271 else |
|
1272 { |
|
1273 EnableHighlight( ETrue ); |
|
1274 } |
|
1275 } |
|
1276 |
|
1277 |
|
1278 // --------------------------------------------------------------------------- |
|
1279 // Handles an addition of new item into tree list. The focused item is kept |
|
1280 // in the same position of the view, and the set of tree items in the view is |
|
1281 // modified to contain the added item when necessary. |
|
1282 // --------------------------------------------------------------------------- |
|
1283 // |
|
1284 void CAknTreeListView::HandleItemAddedEvent( CAknTreeItem* /*aItem*/, TBool aDrawNow ) |
|
1285 { |
|
1286 UpdateVisibleItems(); |
|
1287 if (aDrawNow) |
|
1288 { |
|
1289 UpdateScrollbars(); |
|
1290 } |
|
1291 } |
|
1292 |
|
1293 |
|
1294 // --------------------------------------------------------------------------- |
|
1295 // Handles the movement of a tree item. Movement of focused item has to be |
|
1296 // handled as a special case. |
|
1297 // --------------------------------------------------------------------------- |
|
1298 // |
|
1299 void CAknTreeListView::HandleItemMovedEvent( CAknTreeItem* /*aItem*/ ) |
|
1300 { |
|
1301 // Note: This method cannot deduce, which items in the view have actually |
|
1302 // been changed, unless the it receives information from where the |
|
1303 // specified item was moved. |
|
1304 UpdateVisibleItems(); |
|
1305 UpdateScrollbars(); |
|
1306 } |
|
1307 |
|
1308 |
|
1309 // --------------------------------------------------------------------------- |
|
1310 // Prepares view for the item removal by moving the focus from the removed |
|
1311 // item. |
|
1312 // --------------------------------------------------------------------------- |
|
1313 // |
|
1314 void CAknTreeListView::PrepareForItemRemoval( CAknTreeItem* aItem, TBool /*aDrawNow*/ ) |
|
1315 { |
|
1316 __ASSERT_DEBUG( aItem, User::Invariant() ); |
|
1317 |
|
1318 if ( FocusedItem() == aItem ) |
|
1319 { |
|
1320 TAknTreeIterator iterator = iTree.Iterator(); |
|
1321 |
|
1322 CAknTreeItem* currentItem = FocusedItem(); |
|
1323 |
|
1324 iterator.SetCurrent( currentItem ); |
|
1325 if ( iterator.HasNext() ) |
|
1326 { |
|
1327 // if next item with same parent exists, set focus to it |
|
1328 CAknTreeItem* nextItem = iterator.Next(); |
|
1329 if ( currentItem->Parent() == nextItem->Parent() ) |
|
1330 { |
|
1331 SetFocusedItem( nextItem ); |
|
1332 return; |
|
1333 } |
|
1334 } |
|
1335 |
|
1336 iterator.SetCurrent( currentItem ); |
|
1337 if ( iterator.HasPrevious() ) |
|
1338 { |
|
1339 // otherwise if previous item exists, set focus to it |
|
1340 SetFocusedItem( iterator.Previous() ); |
|
1341 SetFocusIndex( FocusIndex() - 1 ); |
|
1342 } |
|
1343 else |
|
1344 { |
|
1345 // no focus |
|
1346 SetFocusedItem( NULL ); |
|
1347 SetFocusIndex( KMinTInt ); |
|
1348 } |
|
1349 } |
|
1350 } |
|
1351 |
|
1352 |
|
1353 // --------------------------------------------------------------------------- |
|
1354 // Handles the removal of a tree item. |
|
1355 // --------------------------------------------------------------------------- |
|
1356 // |
|
1357 void CAknTreeListView::HandleItemRemovedEvent( CAknTreeItem* /*aItem*/, TBool aDrawNow ) |
|
1358 { |
|
1359 UpdateVisibleItems(); |
|
1360 if (aDrawNow) |
|
1361 { |
|
1362 UpdateScrollbars(); |
|
1363 } |
|
1364 } |
|
1365 |
|
1366 |
|
1367 // --------------------------------------------------------------------------- |
|
1368 // Handles an expansion of a tree node. If the expanded node is focused, it is |
|
1369 // moved upwards in the view enough to make its currently expanded content |
|
1370 // visible. |
|
1371 // --------------------------------------------------------------------------- |
|
1372 // |
|
1373 void CAknTreeListView::HandleNodeExpandedEvent( CAknTreeNode* aNode ) |
|
1374 { |
|
1375 if ( FocusedItem() == aNode ) |
|
1376 { |
|
1377 TInt count = aNode->VisibleDescendantCount(); |
|
1378 TInt index = Min( Max( FocusIndex(), 0 ), |
|
1379 Max( ( iItems.Count() - count ) - 1, 0 ) ); |
|
1380 UpdateVisibleItems( index, aNode ); |
|
1381 } |
|
1382 else |
|
1383 { |
|
1384 UpdateVisibleItems(); |
|
1385 } |
|
1386 UpdateScrollbars(); |
|
1387 } |
|
1388 |
|
1389 |
|
1390 // --------------------------------------------------------------------------- |
|
1391 // Handles a collapse of a tree node. If one of the items in collapsed node |
|
1392 // is focused, the focus has to be moved to collapsed node. |
|
1393 // --------------------------------------------------------------------------- |
|
1394 // |
|
1395 void CAknTreeListView::HandleNodeCollapsedEvent( CAknTreeNode* aNode ) |
|
1396 { |
|
1397 __ASSERT_DEBUG( aNode, User::Invariant() ); |
|
1398 |
|
1399 if ( FocusedItem() && FocusedItem() != aNode ) |
|
1400 { |
|
1401 TAknTreeIterator iterator = iTree.Iterator(); |
|
1402 iterator.SetCurrent( aNode ); |
|
1403 |
|
1404 // Get next visible item after collapsed node. |
|
1405 CAknTreeItem* next = iterator.Next(); |
|
1406 |
|
1407 TInt collapsedIndex = iTree.ItemIndex( aNode ); |
|
1408 TInt focusedIndex = iTree.ItemIndex( FocusedItem() ); |
|
1409 if ( focusedIndex > collapsedIndex ) |
|
1410 { |
|
1411 if ( !next || iTree.ItemIndex( next ) > focusedIndex ) |
|
1412 { |
|
1413 // Move focus to collapsed node from its descendant. |
|
1414 SetFocusedItem( aNode, FocusIndex(), EFalse ); |
|
1415 } |
|
1416 } |
|
1417 } |
|
1418 else if ( FocusedItem() && FocusedItem() == aNode && !FocusedItemVisible() ) |
|
1419 { |
|
1420 // If focused node is not visible, adjust the items so that it becomes |
|
1421 // visible |
|
1422 UpdateViewItemAsVisible( aNode ); |
|
1423 } |
|
1424 |
|
1425 UpdateVisibleItems(); |
|
1426 UpdateScrollbars(); |
|
1427 } |
|
1428 |
|
1429 |
|
1430 // --------------------------------------------------------------------------- |
|
1431 // Handles a change in tree item. |
|
1432 // --------------------------------------------------------------------------- |
|
1433 // |
|
1434 void CAknTreeListView::HandleItemModifiedEvent( CAknTreeItem* /*aItem*/ ) |
|
1435 { |
|
1436 } |
|
1437 |
|
1438 |
|
1439 // --------------------------------------------------------------------------- |
|
1440 // Sets the items to the view from the beginning of the list after the |
|
1441 // tree has been sorted. |
|
1442 // --------------------------------------------------------------------------- |
|
1443 // |
|
1444 void CAknTreeListView::HandleTreeSortedEvent( TBool aDrawNow ) |
|
1445 { |
|
1446 if ( iFlags.IsClear( EFlagSaveFocusAfterSorting) ) |
|
1447 { |
|
1448 TInt count = iItems.Count(); |
|
1449 if ( count > 0) |
|
1450 { |
|
1451 TAknTreeIterator iterator = iTree.Iterator(); |
|
1452 for ( TInt ii = 0; ii < count; ++ii ) |
|
1453 { |
|
1454 iItems[ii].SetItem( iterator.Next() ); |
|
1455 } |
|
1456 |
|
1457 SetFocusIndex( 0 ); |
|
1458 SetFocusedItem( iItems[0].Item() ); |
|
1459 } |
|
1460 else |
|
1461 { |
|
1462 SetFocusIndex( KMinTInt ); |
|
1463 SetFocusedItem( NULL ); |
|
1464 } |
|
1465 } |
|
1466 else |
|
1467 { |
|
1468 TInt count = iItems.Count(); |
|
1469 if ( count > 0) |
|
1470 { |
|
1471 TAknTreeIterator iterator = iTree.Iterator(); |
|
1472 for ( TInt ii = 0; ii < count; ++ii ) |
|
1473 { |
|
1474 iItems[ii].SetItem( iterator.Next() ); |
|
1475 } |
|
1476 } |
|
1477 } |
|
1478 if ( aDrawNow ) |
|
1479 { |
|
1480 UpdateScrollbars(); |
|
1481 } |
|
1482 } |
|
1483 |
|
1484 |
|
1485 // --------------------------------------------------------------------------- |
|
1486 // Updates the view items so that the specified item is located at the |
|
1487 // specified location of the view. The index is adjusted so that the |
|
1488 // beginning of the list is not left empty. |
|
1489 // --------------------------------------------------------------------------- |
|
1490 // |
|
1491 void CAknTreeListView::UpdateVisibleItems( TInt aIndex, CAknTreeItem* aItem ) |
|
1492 { |
|
1493 SetFocusIndex( KMinTInt ); |
|
1494 if ( !iItems.Count() ) |
|
1495 { |
|
1496 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1497 UpdateIndexes(); |
|
1498 #endif |
|
1499 return; |
|
1500 } |
|
1501 |
|
1502 TInt index = Min( aIndex, iTree.VisibleItemIndex( aItem ) ); |
|
1503 |
|
1504 TAknTreeIterator iterator = iTree.Iterator(); |
|
1505 if ( index < 0 || index > iItems.Count() || !aItem ) |
|
1506 { |
|
1507 index = 0; |
|
1508 aItem = iterator.Next(); |
|
1509 } |
|
1510 |
|
1511 iItems[index].SetItem( aItem ); |
|
1512 if ( aItem == FocusedItem() ) |
|
1513 { |
|
1514 SetFocusIndex( index ); |
|
1515 } |
|
1516 |
|
1517 iterator.SetCurrent( aItem ); |
|
1518 for ( TInt ii = index - 1; ii >= 0; --ii ) |
|
1519 { |
|
1520 iItems[ii].SetItem( iterator.Previous() ); |
|
1521 if ( iItems[ii].Item() == FocusedItem() ) |
|
1522 { |
|
1523 SetFocusIndex( ii ); |
|
1524 } |
|
1525 } |
|
1526 |
|
1527 iterator.SetCurrent( aItem ); |
|
1528 for ( TInt ii = index + 1; ii < iItems.Count(); ++ii ) |
|
1529 { |
|
1530 iItems[ii].SetItem( iterator.Next() ); |
|
1531 if ( iItems[ii].Item() == FocusedItem() ) |
|
1532 { |
|
1533 SetFocusIndex( ii ); |
|
1534 } |
|
1535 } |
|
1536 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1537 UpdateIndexes(); |
|
1538 #endif |
|
1539 } |
|
1540 |
|
1541 |
|
1542 // --------------------------------------------------------------------------- |
|
1543 // Updates the view items so that the focused item remains in the same |
|
1544 // position unless the list contains fewer items the view can contain. |
|
1545 // --------------------------------------------------------------------------- |
|
1546 // |
|
1547 void CAknTreeListView::UpdateVisibleItems() |
|
1548 { |
|
1549 // Set the first item in the list focused, if no item is focused. |
|
1550 if ( !FocusedItem() ) |
|
1551 { |
|
1552 TAknTreeIterator iterator = iTree.Iterator(); |
|
1553 if ( iterator.HasNext() ) |
|
1554 { |
|
1555 SetFocusedItem( iterator.Next() ); |
|
1556 SetFocusIndex( KMinTInt ); |
|
1557 |
|
1558 iPreviouslyFocusedItem = FocusedItem(); |
|
1559 } |
|
1560 } |
|
1561 |
|
1562 // Number of items in the expanded part of the tree. |
|
1563 const TInt itemCount = iTree.VisibleItemCount(); |
|
1564 |
|
1565 // Update the set of items in the view. |
|
1566 if ( itemCount <= iItems.Count() ) |
|
1567 { |
|
1568 // Set the tree items in the beginning of the view. |
|
1569 TAknTreeIterator iterator = iTree.Iterator(); |
|
1570 CAknTreeItem* item = iterator.Next(); |
|
1571 SetFocusIndex( KMinTInt ); |
|
1572 for ( TInt ii = 0; ii < iItems.Count(); ++ii ) |
|
1573 { |
|
1574 iItems[ii].SetItem( item ); |
|
1575 if ( item ) |
|
1576 { |
|
1577 if ( item == FocusedItem() ) |
|
1578 { |
|
1579 SetFocusIndex( ii ); |
|
1580 } |
|
1581 item = iterator.Next(); |
|
1582 } |
|
1583 } |
|
1584 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1585 UpdateIndexes(); |
|
1586 #endif |
|
1587 } |
|
1588 else if ( itemCount && iItems.Count() ) |
|
1589 { |
|
1590 if ( FocusedItemVisible() ) |
|
1591 { |
|
1592 // Keep the focused item in position, if possible. |
|
1593 UpdateVisibleItems( FocusIndex(), FocusedItem() ); |
|
1594 } |
|
1595 else if ( iItems[0].Item() ) |
|
1596 { |
|
1597 // Keep the first item in position, if possible. |
|
1598 UpdateVisibleItems( 0, iItems[0].Item() ); |
|
1599 } |
|
1600 else |
|
1601 { |
|
1602 // Set items to the view from the beginning of the list. |
|
1603 UpdateVisibleItems( 0, iTree.VisibleItem( 0 ) ); |
|
1604 } |
|
1605 } |
|
1606 } |
|
1607 |
|
1608 |
|
1609 // --------------------------------------------------------------------------- |
|
1610 // Handles the selection key by marking the item, if marking is ongoing, or |
|
1611 // otherwise selecting the focused item. |
|
1612 // --------------------------------------------------------------------------- |
|
1613 // |
|
1614 void CAknTreeListView::HandleSelectionKeyEvent() |
|
1615 { |
|
1616 CAknTreeItem* item = FocusedItem(); |
|
1617 if ( item ) |
|
1618 { |
|
1619 if ( MarkingOngoing() ) |
|
1620 { |
|
1621 MarkItem( item, !item->IsMarked(), ETrue ); |
|
1622 } |
|
1623 else |
|
1624 { |
|
1625 SelectItem( item, true ); |
|
1626 } |
|
1627 } |
|
1628 } |
|
1629 |
|
1630 |
|
1631 // --------------------------------------------------------------------------- |
|
1632 // Handles right arrow key event. |
|
1633 // --------------------------------------------------------------------------- |
|
1634 // |
|
1635 void CAknTreeListView::HandleRightArrowKeyEvent() |
|
1636 { |
|
1637 if ( AknLayoutUtils::LayoutMirrored() ) |
|
1638 { |
|
1639 AscendFocus(); |
|
1640 } |
|
1641 else |
|
1642 { |
|
1643 DescendFocus(); |
|
1644 } |
|
1645 } |
|
1646 |
|
1647 |
|
1648 // --------------------------------------------------------------------------- |
|
1649 // Handles left arrow key event. |
|
1650 // --------------------------------------------------------------------------- |
|
1651 // |
|
1652 void CAknTreeListView::HandleLeftArrowKeyEvent() |
|
1653 { |
|
1654 if ( AknLayoutUtils::LayoutMirrored() ) |
|
1655 { |
|
1656 DescendFocus(); |
|
1657 } |
|
1658 else |
|
1659 { |
|
1660 AscendFocus(); |
|
1661 } |
|
1662 } |
|
1663 |
|
1664 |
|
1665 // --------------------------------------------------------------------------- |
|
1666 // Handles up arrow key event by moving focus upwards. If the focus is already |
|
1667 // in the top-most item of the list and the list is set looping, the focus is |
|
1668 // moved to the bottom-most item. |
|
1669 // --------------------------------------------------------------------------- |
|
1670 // |
|
1671 void CAknTreeListView::HandleUpArrowKeyEvent() |
|
1672 { |
|
1673 if ( iFlags.IsClear( EFlagSimultaneousMarking ) && |
|
1674 ( iFlags.IsSet( EFlagMark ) || iFlags.IsSet( EFlagUnmark ) ) ) |
|
1675 { |
|
1676 MarkItem( FocusedItem(), iFlags.IsSet( EFlagMark ), ETrue ); |
|
1677 iFlags.Set( EFlagSimultaneousMarking ); |
|
1678 } |
|
1679 |
|
1680 TAknTreeIterator iterator = iTree.Iterator(); |
|
1681 iterator.SetCurrent( FocusedItem() ); |
|
1682 |
|
1683 TInt index = LastVisibleItemIndex(); |
|
1684 if ( iterator.HasPrevious() ) |
|
1685 { |
|
1686 if ( FocusedItemVisible() ) |
|
1687 { |
|
1688 index = Min( |
|
1689 Max( FocusIndex() - 1, FirstVisibleItemIndex() ), index ); |
|
1690 } |
|
1691 else |
|
1692 { |
|
1693 __ASSERT_DEBUG( iItems.Count(), User::Invariant() ); |
|
1694 |
|
1695 TInt firstIndex = iTree.VisibleItemIndex( iItems[0].Item() ); |
|
1696 if ( firstIndex > iTree.VisibleItemIndex( FocusedItem() ) ) |
|
1697 { |
|
1698 index = FirstVisibleItemIndex(); |
|
1699 } |
|
1700 } |
|
1701 SetFocusedItem( iterator.Previous(), index, ETrue ); |
|
1702 } |
|
1703 else if ( IsLooping() ) |
|
1704 { |
|
1705 // Move focus to the bottom-most item in the list. |
|
1706 SetFocusedItem( iterator.Last(), index, ETrue ); |
|
1707 } |
|
1708 |
|
1709 if ( iFlags.IsSet( EFlagSimultaneousMarking ) ) |
|
1710 { |
|
1711 MarkItem( FocusedItem(), iFlags.IsSet( EFlagMark ), ETrue ); |
|
1712 } |
|
1713 } |
|
1714 |
|
1715 |
|
1716 // --------------------------------------------------------------------------- |
|
1717 // Handles down arrow key event by moving focus downwards. If the focus is |
|
1718 // already in the bottom-most item of the list and the list is set looping, |
|
1719 // the focus is moved to the top-most item. |
|
1720 // --------------------------------------------------------------------------- |
|
1721 // |
|
1722 void CAknTreeListView::HandleDownArrowKeyEvent() |
|
1723 { |
|
1724 if ( iFlags.IsClear( EFlagSimultaneousMarking ) && |
|
1725 ( iFlags.IsSet( EFlagMark ) || iFlags.IsSet( EFlagUnmark ) ) ) |
|
1726 { |
|
1727 MarkItem( FocusedItem(), iFlags.IsSet( EFlagMark ), ETrue ); |
|
1728 iFlags.Set( EFlagSimultaneousMarking ); |
|
1729 } |
|
1730 |
|
1731 TAknTreeIterator iterator = iTree.Iterator(); |
|
1732 iterator.SetCurrent( FocusedItem() ); |
|
1733 |
|
1734 TInt index = FirstVisibleItemIndex(); |
|
1735 if ( iterator.HasNext() ) |
|
1736 { |
|
1737 if ( FocusedItemVisible() ) |
|
1738 { |
|
1739 index = Min( Max( FocusIndex() + 1, 0 ), LastVisibleItemIndex() ); |
|
1740 } |
|
1741 else |
|
1742 { |
|
1743 __ASSERT_DEBUG( iItems.Count(), User::Invariant() ); |
|
1744 |
|
1745 TInt firstIndex = iTree.VisibleItemIndex( iItems[0].Item() ); |
|
1746 if ( firstIndex < iTree.VisibleItemIndex( FocusedItem() ) ) |
|
1747 { |
|
1748 index = LastVisibleItemIndex(); |
|
1749 } |
|
1750 } |
|
1751 SetFocusedItem( iterator.Next(), index, ETrue ); |
|
1752 } |
|
1753 else if ( IsLooping() ) |
|
1754 { |
|
1755 // Move focus to the top-most item in the list. |
|
1756 SetFocusedItem( iterator.First(), index, ETrue ); |
|
1757 } |
|
1758 |
|
1759 if ( iFlags.IsSet( EFlagSimultaneousMarking ) ) |
|
1760 { |
|
1761 MarkItem( FocusedItem(), iFlags.IsSet( EFlagMark ), ETrue ); |
|
1762 } |
|
1763 } |
|
1764 |
|
1765 |
|
1766 // --------------------------------------------------------------------------- |
|
1767 // Moves focus deeper in the tree hierarchy. This is done by expanding the |
|
1768 // focused item, if it is a collapsed node; or moving focus to the first child |
|
1769 // of the item, if the item is an expanded node. |
|
1770 // --------------------------------------------------------------------------- |
|
1771 // |
|
1772 void CAknTreeListView::DescendFocus() |
|
1773 { |
|
1774 if ( FocusedItem() ) |
|
1775 { |
|
1776 CAknTreeNode* node = FocusedItem()->Node(); |
|
1777 if ( node ) |
|
1778 { |
|
1779 if ( node->IsExpanded() ) |
|
1780 { |
|
1781 if ( node->ChildCount() ) |
|
1782 { |
|
1783 HandleDownArrowKeyEvent(); |
|
1784 } |
|
1785 } |
|
1786 else |
|
1787 { |
|
1788 iTree.ExpandNode( iTree.Id( node ), ETrue ); |
|
1789 } |
|
1790 } |
|
1791 } |
|
1792 } |
|
1793 |
|
1794 |
|
1795 // --------------------------------------------------------------------------- |
|
1796 // Moves focus higher in the tree hierarchy. This is done by collapsing the |
|
1797 // focused item, if it is an expanded node; or moving focus to the item's |
|
1798 // parent, if the item is a collapsed node or a leaf. |
|
1799 // --------------------------------------------------------------------------- |
|
1800 // |
|
1801 void CAknTreeListView::AscendFocus() |
|
1802 { |
|
1803 if ( FocusedItem() ) |
|
1804 { |
|
1805 CAknTreeNode* node = FocusedItem()->Node(); |
|
1806 if ( node && node->IsExpanded() ) |
|
1807 { |
|
1808 iTree.CollapseNode( iTree.Id( node ), ETrue ); |
|
1809 } |
|
1810 else |
|
1811 { |
|
1812 CAknTreeNode* parent = FocusedItem()->Parent(); |
|
1813 if ( parent && iTree.Id( parent ) != KAknTreeIIDRoot ) |
|
1814 { |
|
1815 TInt index = 0; |
|
1816 for ( TInt ii = 0; ii < iItems.Count(); ++ii ) |
|
1817 { |
|
1818 if ( iItems[ii].Item() == parent ) |
|
1819 { |
|
1820 index = ii; |
|
1821 break; |
|
1822 } |
|
1823 } |
|
1824 |
|
1825 SetFocusedItem( parent, index, ETrue ); |
|
1826 |
|
1827 if ( iFlags.IsSet( EFlagMark ) || iFlags.IsSet( EFlagUnmark ) ) |
|
1828 { |
|
1829 MarkItem( parent, iFlags.IsSet( EFlagMark ), ETrue ); |
|
1830 iFlags.Set( EFlagSimultaneousMarking ); |
|
1831 } |
|
1832 } |
|
1833 } |
|
1834 } |
|
1835 } |
|
1836 |
|
1837 |
|
1838 // --------------------------------------------------------------------------- |
|
1839 // Checks whether the list view is empty. |
|
1840 // --------------------------------------------------------------------------- |
|
1841 // |
|
1842 TBool CAknTreeListView::IsEmpty() const |
|
1843 { |
|
1844 for ( TInt ii = 0; ii < iItems.Count(); ++ii ) |
|
1845 { |
|
1846 if ( iItems[ii].Item() ) |
|
1847 { |
|
1848 // Item found, list is not empty. |
|
1849 return EFalse; |
|
1850 } |
|
1851 } |
|
1852 return ETrue; |
|
1853 } |
|
1854 |
|
1855 |
|
1856 // --------------------------------------------------------------------------- |
|
1857 // Sets the layout for the view from the layout data. |
|
1858 // --------------------------------------------------------------------------- |
|
1859 // |
|
1860 void CAknTreeListView::LayoutView() |
|
1861 { |
|
1862 // Subpane for list and scroll bar. |
|
1863 TInt subpaneVariety = 0; // No find. |
|
1864 TRect subpaneRect = RectFromLayout( Rect(), |
|
1865 AknLayoutScalable_Avkon::listscroll_gen_pane( subpaneVariety ) ); |
|
1866 |
|
1867 // Check scrollbar visibilities to get correct variety for list pane. |
|
1868 TInt listPaneVariety = 1; // No scrollbars. |
|
1869 if ( iScrollbarFrame ) |
|
1870 { |
|
1871 TBool hScrollbar = iScrollbarFrame->ScrollBarVisibility( |
|
1872 CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOff; |
|
1873 TBool vScrollbar = iScrollbarFrame->ScrollBarVisibility( |
|
1874 CEikScrollBar::EVertical ) != CEikScrollBarFrame::EOff; |
|
1875 |
|
1876 // Set list pane variety depending on scrollbar visibilities. |
|
1877 if ( vScrollbar && hScrollbar ) |
|
1878 { |
|
1879 listPaneVariety = 4; |
|
1880 } |
|
1881 else if ( vScrollbar ) |
|
1882 { |
|
1883 listPaneVariety = 0; |
|
1884 } |
|
1885 else if ( hScrollbar ) |
|
1886 { |
|
1887 listPaneVariety = 3; |
|
1888 } |
|
1889 |
|
1890 // Layout scrollbars. |
|
1891 TInt sbVariety = vScrollbar ? 2 : 1; // horizontal scrollbar variety |
|
1892 AknLayoutUtils::LayoutHorizontalScrollBar( iScrollbarFrame, subpaneRect, |
|
1893 AknLayoutScalable_Avkon::scroll_pane( sbVariety ).LayoutLine() ); |
|
1894 |
|
1895 if ( hScrollbar ) |
|
1896 { |
|
1897 AknLayoutUtils::LayoutVerticalScrollBar( iScrollbarFrame, subpaneRect, |
|
1898 AknLayoutScalable_Avkon::scroll_pane_cp14().LayoutLine() ); |
|
1899 } |
|
1900 else |
|
1901 { |
|
1902 sbVariety = 0; // vertical scrollbar variety |
|
1903 AknLayoutUtils::LayoutVerticalScrollBar( iScrollbarFrame, subpaneRect, |
|
1904 AknLayoutScalable_Avkon::scroll_pane( sbVariety ).LayoutLine() ); |
|
1905 } |
|
1906 } |
|
1907 |
|
1908 // List. |
|
1909 TRect listRect = RectFromLayout( subpaneRect, |
|
1910 AknLayoutScalable_Avkon::list_gen_pane( listPaneVariety ) ); |
|
1911 |
|
1912 // Hierarchial list item. |
|
1913 TInt itemVariety = 0; |
|
1914 TRect itemRect = RectFromLayout( listRect, |
|
1915 AknLayoutScalable_Avkon::list_single_graphic_hl_pane( itemVariety ) ); |
|
1916 |
|
1917 // Rect for structure line element. |
|
1918 TInt lineVariety = 0; // Type. |
|
1919 TRect lineSegmentRect = RectFromLayout( itemRect, |
|
1920 AknLayoutScalable_Avkon::list_single_graphic_hl_pane_g1( lineVariety ) ); |
|
1921 |
|
1922 // Minimum item width. |
|
1923 TRect minimumItemRect = RectFromLayout( itemRect, |
|
1924 AknLayoutScalable_Avkon::aid_size_min_hl_cp1() ); |
|
1925 |
|
1926 // Calculate horizontal view span, which can be negative when items of |
|
1927 // minimum width do not fit within the view. |
|
1928 iHorizontalViewSpan = ( itemRect.Width() - minimumItemRect.Width() ) / |
|
1929 lineSegmentRect.Width(); |
|
1930 |
|
1931 // Count the maximum number of visible items for the new size. |
|
1932 TInt itemCountLimit = Max( 0, listRect.Height() / itemRect.Height() ); |
|
1933 itemCountLimit += KAdditionalItems; |
|
1934 |
|
1935 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1936 iItemCountLimit = itemCountLimit; |
|
1937 #endif |
|
1938 |
|
1939 if ( iItems.Count() > itemCountLimit ) |
|
1940 { |
|
1941 // Remove items from the view. |
|
1942 for ( TInt ii = iItems.Count() - 1; ii >= itemCountLimit; --ii ) |
|
1943 { |
|
1944 iItems.Remove( ii ); |
|
1945 } |
|
1946 } |
|
1947 else |
|
1948 { |
|
1949 // Add items to the view. |
|
1950 for ( TInt ii = iItems.Count(); ii < itemCountLimit; ++ii ) |
|
1951 { |
|
1952 // This should not fail, if enough space was reserved for the |
|
1953 // array, and if it fails, it results only fewer items being |
|
1954 // shown in the list. |
|
1955 iItems.Append( TAknTreeListViewItem() ); |
|
1956 } |
|
1957 } |
|
1958 |
|
1959 // Get iterator and set it to point at the first item in the view, or at |
|
1960 // the first item in the list, if the view does not contain any items. |
|
1961 TAknTreeIterator iterator = iTree.Iterator(); |
|
1962 CAknTreeItem* first = iItems.Count() ? iItems[0].Item() : NULL; |
|
1963 if ( first ) |
|
1964 { |
|
1965 iterator.SetCurrent( first ); |
|
1966 iterator.Previous(); |
|
1967 } |
|
1968 |
|
1969 // Update items and their rectangles. |
|
1970 for ( TInt ii = 0; ii < iItems.Count(); ++ii ) |
|
1971 { |
|
1972 CAknTreeItem* item = iterator.Next(); |
|
1973 iItems[ii].SetItem( item ); |
|
1974 iItems[ii].SetRect( itemRect ); |
|
1975 itemRect.Move( 0, itemRect.Height() ); |
|
1976 |
|
1977 // this is needed also when feature is not enabled |
|
1978 iItems[ii].SetView( this ); |
|
1979 |
|
1980 |
|
1981 if ( item && FocusedItem() == item ) |
|
1982 { |
|
1983 SetFocusIndex( ii ); |
|
1984 } |
|
1985 } |
|
1986 |
|
1987 TRect viewRect( listRect ); |
|
1988 |
|
1989 // Fill whole control area with list items when physics enabled |
|
1990 // and threre is no horizontal scrollbar. |
|
1991 if ( iScrollbarFrame && |
|
1992 iScrollbarFrame->ScrollBarVisibility( CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOn && |
|
1993 viewRect.Height() < Rect().Height() ) |
|
1994 { |
|
1995 viewRect.iTl.iY = Rect().iTl.iY; |
|
1996 viewRect.iBr.iY = Rect().iBr.iY; |
|
1997 } |
|
1998 iPhysicsHandler->SetViewRect( viewRect ); |
|
1999 iPhysicsHandler->SetItemHeight( itemRect.Height() ); |
|
2000 TRAP_IGNORE( InitPhysicsL() ); |
|
2001 } |
|
2002 |
|
2003 |
|
2004 // --------------------------------------------------------------------------- |
|
2005 // Updates the span, thumb size and position for both of the scrollbars. New |
|
2006 // layout for the view is applied, if the visibility of either of the |
|
2007 // scrollbars changes. |
|
2008 // --------------------------------------------------------------------------- |
|
2009 // |
|
2010 void CAknTreeListView::UpdateScrollbars() |
|
2011 { |
|
2012 if ( iScrollbarFrame ) |
|
2013 { |
|
2014 iPhysicsHandler->UpdateScrollIndex( iScrollPhysicsTop ); |
|
2015 iScrollPhysicsTop = ETrue; |
|
2016 |
|
2017 // Get values for horizontal scrollbar. |
|
2018 TInt hThumbPos = iViewLevel; |
|
2019 TInt hThumbSpan = iHorizontalViewSpan; |
|
2020 TInt hScrollSpan = Max( hThumbPos + hThumbSpan, iMaxViewLevel ); |
|
2021 |
|
2022 if ( iHorizontalViewSpan <= 1 && iItems.Count() ) |
|
2023 { |
|
2024 TInt a = iItems[0].Rect().Width(); |
|
2025 TInt b = iItems[0].LineSegmentRect( 0 ).Width(); |
|
2026 TInt c = iItems[0].ItemRect( iViewLevel, Indention(), |
|
2027 IndentionWidth() ).Width(); |
|
2028 hThumbSpan = a/b; |
|
2029 hScrollSpan = Max( hThumbPos + hThumbSpan, c/b ); |
|
2030 } |
|
2031 |
|
2032 if ( AknLayoutUtils::LayoutMirrored() ) |
|
2033 { |
|
2034 hThumbPos = hScrollSpan - ( hThumbPos + hThumbSpan ); |
|
2035 } |
|
2036 TEikScrollBarModel hModel( hScrollSpan, hThumbSpan, hThumbPos ); |
|
2037 |
|
2038 |
|
2039 // Values for empty vertical scrollbar. |
|
2040 TInt vThumbSpan( 10 ); // nonzero value is needed to draw "empty scrollbar" |
|
2041 TInt vThumbPos( 0 ); |
|
2042 TInt vScrollSpan( 0 ); |
|
2043 |
|
2044 TAknTreeIterator iterator = iTree.Iterator(); |
|
2045 if ( iterator.HasNext() ) |
|
2046 { |
|
2047 iPhysicsHandler->GetVScrollbarParams( vThumbSpan, |
|
2048 vThumbPos, |
|
2049 vScrollSpan ); |
|
2050 } |
|
2051 TEikScrollBarModel vModel( vScrollSpan, vThumbSpan, vThumbPos ); |
|
2052 |
|
2053 |
|
2054 // Change visibilities when necessary. |
|
2055 CEikScrollBarFrame::TScrollBarVisibility hVisibility = |
|
2056 CEikScrollBarFrame::EOn; |
|
2057 CEikScrollBarFrame::TScrollBarVisibility vVisibility = |
|
2058 CEikScrollBarFrame::EOn; |
|
2059 |
|
2060 if ( iMaxViewLevel <= iHorizontalViewSpan ) |
|
2061 { |
|
2062 hVisibility = CEikScrollBarFrame::EOff; |
|
2063 // when horizontal scrollbar not visible, adjust view to left |
|
2064 iViewLevel = 0; |
|
2065 } |
|
2066 |
|
2067 if ( hVisibility != iScrollbarFrame->ScrollBarVisibility( |
|
2068 CEikScrollBar::EHorizontal ) || |
|
2069 vVisibility != iScrollbarFrame->ScrollBarVisibility( |
|
2070 CEikScrollBar::EVertical ) ) |
|
2071 { |
|
2072 TRAP_IGNORE( iScrollbarFrame->SetScrollBarVisibilityL( |
|
2073 hVisibility, vVisibility ) ); |
|
2074 |
|
2075 // Set new model for scrollbars. |
|
2076 iScrollbarFrame->Tile( &hModel, &vModel ); |
|
2077 |
|
2078 LayoutView(); |
|
2079 UpdateScrollbars(); // Recursion |
|
2080 |
|
2081 // Update animation in case that scrollbar visibility change |
|
2082 // has affected the highlight size of focused item. |
|
2083 UpdateAnimation(); |
|
2084 } |
|
2085 else |
|
2086 { |
|
2087 // Set new model for scrollbars. |
|
2088 iScrollbarFrame->Tile( &hModel, &vModel ); |
|
2089 } |
|
2090 } |
|
2091 |
|
2092 } |
|
2093 |
|
2094 |
|
2095 |
|
2096 |
|
2097 |
|
2098 |
|
2099 // --------------------------------------------------------------------------- |
|
2100 // Adjusts the horizontal position of the view items. The adjustment is made |
|
2101 // so that the beginning of the focused item is visible, including one |
|
2102 // indention segment in front of the item, if it has such, and if possible, |
|
2103 // the visible item width exeeds the specified minimum width. |
|
2104 // --------------------------------------------------------------------------- |
|
2105 // |
|
2106 void CAknTreeListView::UpdateViewLevel() |
|
2107 { |
|
2108 if ( FocusedItemVisible() ) |
|
2109 { |
|
2110 __ASSERT_DEBUG( FocusedItem(), User::Invariant() ); |
|
2111 |
|
2112 // Adjust view's horizontal position. |
|
2113 TInt itemLevel = Indention() ? FocusedItem()->Level() : 1; |
|
2114 TInt maxViewLevel = Max( itemLevel - 2, 0 ); |
|
2115 if ( iViewLevel > maxViewLevel ) |
|
2116 { |
|
2117 // The beginning of the focused item is not seen, move the view |
|
2118 // so that the beginning of focused item and possibly one |
|
2119 // indention segment in front of it can be seen. |
|
2120 iViewLevel = maxViewLevel; |
|
2121 } |
|
2122 else if ( iViewLevel < maxViewLevel ) |
|
2123 { |
|
2124 // View is moved until the visible part of the item exeeds the |
|
2125 // specified minimum, and if the minimum cannot be exeeded, the |
|
2126 // beginning of the item has to remain visible. |
|
2127 TAknTreeListViewItem viewItem = iItems[FocusIndex()]; |
|
2128 TInt minimumWidth = FocusedItem()->MinimumSize().iWidth; |
|
2129 TInt indentCount = ( itemLevel - 1 ) - iViewLevel; |
|
2130 TInt lineWidth = viewItem.Rect().Width(); |
|
2131 TInt indentWidth = ( IndentionWidth() < 0 ) ? |
|
2132 viewItem.LineSegmentWidth() : IndentionWidth(); |
|
2133 TInt itemWidth = lineWidth - indentCount * indentWidth; |
|
2134 while ( itemWidth < minimumWidth && iViewLevel < maxViewLevel ) |
|
2135 { |
|
2136 iViewLevel += 1; |
|
2137 itemWidth += indentWidth; |
|
2138 } |
|
2139 } |
|
2140 } |
|
2141 } |
|
2142 |
|
2143 |
|
2144 // --------------------------------------------------------------------------- |
|
2145 // Updates the highlight animation. |
|
2146 // --------------------------------------------------------------------------- |
|
2147 // |
|
2148 TBool CAknTreeListView::UpdateAnimation() const |
|
2149 { |
|
2150 if ( FocusedItemVisible() && iAnimation ) |
|
2151 { |
|
2152 TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, |
|
2153 Indention(), IndentionWidth() ); |
|
2154 return UpdateAnimation( rect ); |
|
2155 } |
|
2156 return EFalse; |
|
2157 } |
|
2158 |
|
2159 |
|
2160 TBool CAknTreeListView::UpdateAnimation( const TRect& aRect ) const |
|
2161 { |
|
2162 if ( !iAnimation ) |
|
2163 { |
|
2164 return EFalse; |
|
2165 } |
|
2166 |
|
2167 if ( iAnimation->Size() != aRect.Size() || iAnimation->NeedsInputLayer() ) |
|
2168 { |
|
2169 iFlags.Clear( EFlagUpdateBackground ); |
|
2170 TRAPD( error, ResizeAnimationL( aRect.Size(), ETrue ) ) |
|
2171 if ( error ) |
|
2172 { |
|
2173 delete iAnimation; |
|
2174 iAnimation = NULL; |
|
2175 return EFalse; |
|
2176 } |
|
2177 } |
|
2178 else if ( iFlags.IsSet( EFlagUpdateBackground ) ) |
|
2179 { |
|
2180 iFlags.Clear( EFlagUpdateBackground ); |
|
2181 if ( iAnimation->InputRgbGc() ) |
|
2182 { |
|
2183 DrawHighlightBackground( *iAnimation->InputRgbGc() ); |
|
2184 if ( iAnimation->UpdateOutput() != KErrNone ) |
|
2185 { |
|
2186 delete iAnimation; |
|
2187 iAnimation = NULL; |
|
2188 return EFalse; |
|
2189 } |
|
2190 } |
|
2191 } |
|
2192 return ETrue; |
|
2193 } |
|
2194 |
|
2195 |
|
2196 // --------------------------------------------------------------------------- |
|
2197 // Sets focused item. |
|
2198 // --------------------------------------------------------------------------- |
|
2199 // |
|
2200 void CAknTreeListView::SetFocusedItem( CAknTreeItem* aFocusedItem ) |
|
2201 { |
|
2202 if ( iAnimation ) |
|
2203 { |
|
2204 if ( !iFocusedItem && aFocusedItem ) |
|
2205 { |
|
2206 iAnimation->Start(); |
|
2207 } |
|
2208 else if ( !aFocusedItem ) |
|
2209 { |
|
2210 iAnimation->Stop(); |
|
2211 } |
|
2212 } |
|
2213 |
|
2214 if ( iFocusedItem != aFocusedItem ) |
|
2215 { |
|
2216 iFocusedItem = aFocusedItem; |
|
2217 |
|
2218 // Although the focused item is changed even though the list itself |
|
2219 // is not focused, the client is notified of focus change only when |
|
2220 // list is set focused. |
|
2221 if ( IsFocused() ) |
|
2222 { |
|
2223 ReportTreeListEvent( MAknTreeListObserver::EItemFocused, |
|
2224 iTree.Id( iFocusedItem ) ); |
|
2225 } |
|
2226 } |
|
2227 } |
|
2228 |
|
2229 |
|
2230 // --------------------------------------------------------------------------- |
|
2231 // Checks whether the focused item is currently visible. |
|
2232 // --------------------------------------------------------------------------- |
|
2233 // |
|
2234 TBool CAknTreeListView::FocusedItemVisible() const |
|
2235 { |
|
2236 if ( iFocusedItem && iFocusedItemIndex >= 0 && |
|
2237 iFocusedItemIndex < iItems.Count() ) |
|
2238 { |
|
2239 if ( iPhysicsHandler->FocusedItemVisible( iFocusedItemIndex ) ) |
|
2240 { |
|
2241 return ETrue; |
|
2242 } |
|
2243 } |
|
2244 return EFalse; |
|
2245 } |
|
2246 |
|
2247 |
|
2248 // --------------------------------------------------------------------------- |
|
2249 // Sets the focused item index. |
|
2250 // --------------------------------------------------------------------------- |
|
2251 // |
|
2252 void CAknTreeListView::SetFocusIndex( TInt aIndex ) |
|
2253 { |
|
2254 if ( iFocusedItemIndex != aIndex ) |
|
2255 { |
|
2256 iFocusedItemIndex = aIndex; |
|
2257 iFlags.Set( EFlagUpdateBackground ); |
|
2258 |
|
2259 if ( iAnimation ) |
|
2260 { |
|
2261 if ( aIndex >= 0 && aIndex < iItems.Count() ) |
|
2262 { |
|
2263 iAnimation->Continue(); |
|
2264 } |
|
2265 else |
|
2266 { |
|
2267 iAnimation->Pause(); |
|
2268 } |
|
2269 } |
|
2270 } |
|
2271 } |
|
2272 |
|
2273 |
|
2274 // --------------------------------------------------------------------------- |
|
2275 // Return the index of focused item. |
|
2276 // --------------------------------------------------------------------------- |
|
2277 // |
|
2278 TInt CAknTreeListView::FocusIndex() const |
|
2279 { |
|
2280 return iFocusedItemIndex; |
|
2281 } |
|
2282 |
|
2283 |
|
2284 // --------------------------------------------------------------------------- |
|
2285 // Creates highlight animation for the list view. |
|
2286 // --------------------------------------------------------------------------- |
|
2287 // |
|
2288 void CAknTreeListView::CreateAnimationL() |
|
2289 { |
|
2290 delete iAnimation; iAnimation = NULL; |
|
2291 |
|
2292 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2293 MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
2294 if ( transApi && transApi->VerifyKml() == KErrNone ) |
|
2295 { |
|
2296 return; |
|
2297 } |
|
2298 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2299 |
|
2300 iAnimation = CAknsEffectAnim::NewL( this ); |
|
2301 if ( !iAnimation->ConstructFromSkinL( iAnimationIID ) ) |
|
2302 { |
|
2303 User::Leave( KErrNotFound ); |
|
2304 } |
|
2305 } |
|
2306 |
|
2307 |
|
2308 // --------------------------------------------------------------------------- |
|
2309 // Draws animation background to given graphic context. |
|
2310 // --------------------------------------------------------------------------- |
|
2311 // |
|
2312 TBool CAknTreeListView::DrawHighlightBackground( CFbsBitGc& aGc ) const |
|
2313 { |
|
2314 if ( iAnimation && FocusedItemVisible() ) |
|
2315 { |
|
2316 TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, |
|
2317 Indention(), IndentionWidth() ); |
|
2318 |
|
2319 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
2320 |
|
2321 return AknsDrawUtils::DrawBackground( AknsUtils::SkinInstance(), cc, |
|
2322 this, aGc, TPoint(), rect, KAknsDrawParamBottomLevelRGBOnly ); |
|
2323 } |
|
2324 return EFalse; |
|
2325 } |
|
2326 |
|
2327 |
|
2328 // --------------------------------------------------------------------------- |
|
2329 // Resize animation. |
|
2330 // --------------------------------------------------------------------------- |
|
2331 // |
|
2332 void CAknTreeListView::ResizeAnimationL( const TSize& aHighlightSize, |
|
2333 TBool aAboutToStart ) const |
|
2334 { |
|
2335 iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart ); |
|
2336 |
|
2337 if ( iAnimation->InputRgbGc() ) |
|
2338 { |
|
2339 DrawHighlightBackground( *iAnimation->InputRgbGc() ); |
|
2340 } |
|
2341 |
|
2342 iAnimation->EndConfigInputLayersL(); |
|
2343 } |
|
2344 |
|
2345 |
|
2346 // --------------------------------------------------------------------------- |
|
2347 // Draws animation. |
|
2348 // --------------------------------------------------------------------------- |
|
2349 // |
|
2350 TBool CAknTreeListView::DrawAnimation( CBitmapContext& aGc, |
|
2351 const TRect& aRect ) const |
|
2352 { |
|
2353 if ( !UpdateAnimation( aRect ) ) |
|
2354 { |
|
2355 return EFalse; |
|
2356 } |
|
2357 |
|
2358 return iAnimation->Render( aGc, aRect ); |
|
2359 } |
|
2360 |
|
2361 |
|
2362 // --------------------------------------------------------------------------- |
|
2363 // Draws highlight to the given rectangle. |
|
2364 // --------------------------------------------------------------------------- |
|
2365 // |
|
2366 void CAknTreeListView::DrawHighlight( CWindowGc& aGc, |
|
2367 const TRect& aRect, TBool aPressedDown ) const |
|
2368 { |
|
2369 TRect newRect( aRect ); |
|
2370 newRect.iBr.iY -= Offset(); |
|
2371 newRect.iTl.iY -= Offset(); |
|
2372 |
|
2373 TAknLayoutRect tlRect; |
|
2374 tlRect.LayoutRect( newRect, |
|
2375 SkinLayout::List_highlight_skin_placing__general__Line_2() ); |
|
2376 |
|
2377 TAknLayoutRect brRect; |
|
2378 brRect.LayoutRect( newRect, |
|
2379 SkinLayout::List_highlight_skin_placing__general__Line_5() ); |
|
2380 |
|
2381 TRect outerRect( tlRect.Rect().iTl, brRect.Rect().iBr ); |
|
2382 TRect innerRect( tlRect.Rect().iBr, brRect.Rect().iTl ); |
|
2383 |
|
2384 // No pressed highlight if single click enabled |
|
2385 if ( SingleClickEnabled() ) |
|
2386 { |
|
2387 aPressedDown = EFalse; |
|
2388 } |
|
2389 |
|
2390 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
2391 AknsDrawUtils::DrawFrame( skin, aGc, outerRect, innerRect, |
|
2392 aPressedDown ? |
|
2393 KAknsIIDQsnFrListPressed : KAknsIIDQsnFrList, |
|
2394 KAknsIIDDefault ); |
|
2395 } |
|
2396 |
|
2397 |
|
2398 // --------------------------------------------------------------------------- |
|
2399 // Handles selection of the specified item. If the item is collapsed node, it |
|
2400 // is expande; if the item is expanded node, it is collapsed; or if it is a |
|
2401 // leaf, the selection event is sent to observers of the list. |
|
2402 // --------------------------------------------------------------------------- |
|
2403 // |
|
2404 void CAknTreeListView::SelectItem( CAknTreeItem* aItem, bool aKeyPressed ) |
|
2405 { |
|
2406 __ASSERT_DEBUG( aItem, User::Invariant() ); |
|
2407 |
|
2408 CAknTreeNode* node = aItem->Node(); |
|
2409 if ( node ) |
|
2410 { |
|
2411 if ( node->IsExpanded() ) |
|
2412 { |
|
2413 iTree.CollapseNode( iTree.Id( node ), ETrue ); |
|
2414 } |
|
2415 else |
|
2416 { |
|
2417 iTree.ExpandNode( iTree.Id( node ), ETrue ); |
|
2418 } |
|
2419 } |
|
2420 else if ( aKeyPressed || iPreviouslyFocusedItem == aItem |
|
2421 || SingleClickEnabled() ) |
|
2422 { |
|
2423 // Notify client of selection event. |
|
2424 ReportTreeListEvent( MAknTreeListObserver::EItemSelected, |
|
2425 iTree.Id( aItem ) ); |
|
2426 } |
|
2427 } |
|
2428 |
|
2429 |
|
2430 // --------------------------------------------------------------------------- |
|
2431 // Changes the marking of specified item, when marking is enabled. |
|
2432 // --------------------------------------------------------------------------- |
|
2433 // |
|
2434 void CAknTreeListView::MarkItem( CAknTreeItem* aItem, TBool aMarked, |
|
2435 TBool aDrawNow ) |
|
2436 { |
|
2437 if ( iFlags.IsSet( EFlagMarkingEnabled ) ) |
|
2438 { |
|
2439 TAknTreeItemID item = iTree.Id( aItem ); |
|
2440 if ( item != KAknTreeIIDNone ) |
|
2441 { |
|
2442 iTree.SetMarked( item, aMarked, aDrawNow ); |
|
2443 if ( FocusedItem() == aItem ) |
|
2444 { |
|
2445 UpdateMSKCommand(); |
|
2446 } |
|
2447 } |
|
2448 } |
|
2449 } |
|
2450 |
|
2451 |
|
2452 // --------------------------------------------------------------------------- |
|
2453 // Changes the marking of specified items, when marking is enabled. |
|
2454 // --------------------------------------------------------------------------- |
|
2455 // |
|
2456 void CAknTreeListView::MarkItems( CAknTreeItem* aFirst, CAknTreeItem* aLast, |
|
2457 TBool aMarked, TBool aDrawNow ) |
|
2458 { |
|
2459 if ( iFlags.IsSet( EFlagMarkingEnabled ) ) |
|
2460 { |
|
2461 TAknTreeIterator iterator = iTree.Iterator(); |
|
2462 |
|
2463 TInt first = iTree.VisibleItemIndex( aFirst ); |
|
2464 TInt last = iTree.VisibleItemIndex( aLast ); |
|
2465 if ( first != KErrNotFound && last != KErrNotFound ) |
|
2466 { |
|
2467 TAknTreeIterator iterator = iTree.Iterator(); |
|
2468 CAknTreeItem* item = NULL; |
|
2469 if ( first < last ) |
|
2470 { |
|
2471 item = aFirst; |
|
2472 iterator.SetCurrent( aFirst ); |
|
2473 } |
|
2474 else |
|
2475 { |
|
2476 item = aLast; |
|
2477 iterator.SetCurrent( aLast ); |
|
2478 aLast = aFirst; |
|
2479 } |
|
2480 |
|
2481 while ( item && item != aLast && iterator.HasNext() ) |
|
2482 { |
|
2483 MarkItem( item, aMarked, EFalse ); |
|
2484 item = iterator.Next(); |
|
2485 } |
|
2486 |
|
2487 MarkItem( aLast, aMarked, aDrawNow ); |
|
2488 } |
|
2489 } |
|
2490 } |
|
2491 |
|
2492 |
|
2493 // --------------------------------------------------------------------------- |
|
2494 // Begins marking. |
|
2495 // --------------------------------------------------------------------------- |
|
2496 // |
|
2497 void CAknTreeListView::BeginMarkingL() |
|
2498 { |
|
2499 __ASSERT_DEBUG( iFlags.IsClear( EFlagUnmark ), User::Invariant() ); |
|
2500 __ASSERT_DEBUG( iFlags.IsClear( EFlagMark ), User::Invariant() ); |
|
2501 |
|
2502 if ( iFlags.IsSet( EFlagMarkingEnabled ) && FocusedItem() ) |
|
2503 { |
|
2504 if ( FocusedItem()->IsMarked() ) |
|
2505 { |
|
2506 iFlags.Set( EFlagUnmark ); |
|
2507 } |
|
2508 else |
|
2509 { |
|
2510 iFlags.Set( EFlagMark ); |
|
2511 } |
|
2512 |
|
2513 // Start long press timer to enable marking mode after delay. |
|
2514 StartLongPressTimerL(); |
|
2515 |
|
2516 // Set view as cba observer. |
|
2517 CEikButtonGroupContainer* cba; |
|
2518 MopGetObject( cba ); |
|
2519 CAknEnv::Static()->RequestCommandMediationL( *cba, *this ); |
|
2520 } |
|
2521 } |
|
2522 |
|
2523 |
|
2524 // --------------------------------------------------------------------------- |
|
2525 // Ends ongoing marking. |
|
2526 // --------------------------------------------------------------------------- |
|
2527 // |
|
2528 void CAknTreeListView::EndMarking() |
|
2529 { |
|
2530 __ASSERT_DEBUG( iFlags.IsSet( EFlagMark ) || iFlags.IsSet( EFlagUnmark ), |
|
2531 User::Invariant() ); |
|
2532 |
|
2533 // Stop long press timer. |
|
2534 if ( iLongPressTimer && iLongPressTimer->IsActive() ) |
|
2535 { |
|
2536 iLongPressTimer->Cancel(); |
|
2537 } |
|
2538 |
|
2539 // Exits marking mode. |
|
2540 if ( iFlags.IsSet( EFlagMarkingMode ) ) |
|
2541 { |
|
2542 ExitMarkingMode(); |
|
2543 } |
|
2544 |
|
2545 // Remove MSK observer. |
|
2546 CEikButtonGroupContainer* cba; |
|
2547 MopGetObject( cba ); |
|
2548 CAknEnv::Static()->EndCommandMediation( *this ); |
|
2549 |
|
2550 iFlags.Clear( EFlagMark ); |
|
2551 iFlags.Clear( EFlagUnmark ); |
|
2552 iFlags.Clear( EFlagSimultaneousMarking ); |
|
2553 } |
|
2554 |
|
2555 |
|
2556 // --------------------------------------------------------------------------- |
|
2557 // Checks whether marking is currently ongoing. |
|
2558 // --------------------------------------------------------------------------- |
|
2559 // |
|
2560 TBool CAknTreeListView::MarkingOngoing() const |
|
2561 { |
|
2562 return iFlags.IsSet( EFlagUnmark ) || iFlags.IsSet( EFlagMark ); |
|
2563 } |
|
2564 |
|
2565 |
|
2566 // --------------------------------------------------------------------------- |
|
2567 // Starts the long press timer. |
|
2568 // --------------------------------------------------------------------------- |
|
2569 // |
|
2570 void CAknTreeListView::StartLongPressTimerL() |
|
2571 { |
|
2572 if ( iLongPressTimer ) |
|
2573 { |
|
2574 if ( iLongPressTimer->IsActive() ) |
|
2575 { |
|
2576 iLongPressTimer->Cancel(); |
|
2577 } |
|
2578 |
|
2579 iLongPressTimer->Start( KLongPressInterval, KLongPressInterval, |
|
2580 TCallBack( ReportLongPressL, this ) ); |
|
2581 } |
|
2582 } |
|
2583 |
|
2584 |
|
2585 // --------------------------------------------------------------------------- |
|
2586 // Callback method for long press timer. |
|
2587 // --------------------------------------------------------------------------- |
|
2588 // |
|
2589 TInt CAknTreeListView::ReportLongPressL( TAny* aThis ) |
|
2590 { |
|
2591 __ASSERT_DEBUG( aThis, User::Invariant() ); |
|
2592 static_cast<CAknTreeListView*>( aThis )->DoHandleLongPressL(); |
|
2593 return NULL; |
|
2594 } |
|
2595 |
|
2596 |
|
2597 // --------------------------------------------------------------------------- |
|
2598 // Handles long press. |
|
2599 // --------------------------------------------------------------------------- |
|
2600 // |
|
2601 void CAknTreeListView::DoHandleLongPressL() |
|
2602 { |
|
2603 if ( iFlags.IsClear( EFlagMarkingMode ) ) |
|
2604 { |
|
2605 EnterMarkingMode(); |
|
2606 } |
|
2607 } |
|
2608 |
|
2609 |
|
2610 // --------------------------------------------------------------------------- |
|
2611 // Enters marking mode. |
|
2612 // --------------------------------------------------------------------------- |
|
2613 // |
|
2614 void CAknTreeListView::EnterMarkingMode() |
|
2615 { |
|
2616 CEikButtonGroupContainer* bgc; |
|
2617 CCoeControl* MSK = NULL; |
|
2618 MopGetObject( bgc ); |
|
2619 if ( bgc ) |
|
2620 { |
|
2621 CEikCba* cba = static_cast<CEikCba*>( bgc->ButtonGroup() ); |
|
2622 if ( cba ) |
|
2623 { |
|
2624 MSK = cba->Control( 3 ); |
|
2625 } |
|
2626 } |
|
2627 |
|
2628 TInt newResourceId = NULL; |
|
2629 if ( MSK && FocusedItem() ) |
|
2630 { |
|
2631 if ( FocusedItem()->IsMarked() ) |
|
2632 { |
|
2633 newResourceId = R_AVKON_SOFTKEY_UNMARK; |
|
2634 } |
|
2635 else |
|
2636 { |
|
2637 newResourceId = R_AVKON_SOFTKEY_MARK; |
|
2638 } |
|
2639 } |
|
2640 |
|
2641 if ( newResourceId ) |
|
2642 { |
|
2643 TRAPD( err, bgc->AddCommandToStackL( 3, newResourceId ) ); |
|
2644 if ( !err ) |
|
2645 { |
|
2646 ReportTreeListEvent( MAknTreeListObserver::EMarkingModeEnabled, |
|
2647 iTree.Id( FocusedItem() ) ); |
|
2648 iFlags.Set( EFlagMarkingMode ); |
|
2649 bgc->DrawNow(); |
|
2650 } |
|
2651 } |
|
2652 } |
|
2653 |
|
2654 |
|
2655 // --------------------------------------------------------------------------- |
|
2656 // Exits marking mode. |
|
2657 // --------------------------------------------------------------------------- |
|
2658 // |
|
2659 void CAknTreeListView::ExitMarkingMode() |
|
2660 { |
|
2661 if ( iFlags.IsSet( EFlagMarkingMode ) ) |
|
2662 { |
|
2663 CEikButtonGroupContainer* bgc = NULL; |
|
2664 CCoeControl* MSK = NULL; |
|
2665 MopGetObject( bgc ); |
|
2666 if ( bgc ) |
|
2667 { |
|
2668 CEikCba* cba = static_cast<CEikCba*>( bgc->ButtonGroup() ); |
|
2669 if ( cba ) |
|
2670 { |
|
2671 MSK = cba->Control( 3 ); |
|
2672 if ( MSK && ( cba->ControlId( MSK ) == EAknSoftkeyMark || |
|
2673 cba->ControlId( MSK ) == EAknSoftkeyUnmark ) ) |
|
2674 { |
|
2675 bgc->RemoveCommandFromStack( 3, cba->ControlId( MSK ) ); |
|
2676 } |
|
2677 } |
|
2678 } |
|
2679 ReportTreeListEvent( MAknTreeListObserver::EMarkingModeDisabled, |
|
2680 iTree.Id( FocusedItem() ) ); |
|
2681 iFlags.Clear( EFlagMarkingMode ); |
|
2682 } |
|
2683 } |
|
2684 |
|
2685 |
|
2686 // --------------------------------------------------------------------------- |
|
2687 // Updates MSK command. |
|
2688 // --------------------------------------------------------------------------- |
|
2689 // |
|
2690 void CAknTreeListView::UpdateMSKCommand() |
|
2691 { |
|
2692 CEikButtonGroupContainer* bgc = NULL; |
|
2693 MopGetObject( bgc ); |
|
2694 if ( bgc ) |
|
2695 { |
|
2696 TInt newResourceId = NULL; |
|
2697 MEikButtonGroup* bg = bgc->ButtonGroup(); |
|
2698 if ( FocusedItem() && bg ) |
|
2699 { |
|
2700 if ( FocusedItem()->IsMarked() && |
|
2701 bg->CommandId( 3 ) == EAknSoftkeyMark ) |
|
2702 { |
|
2703 newResourceId = R_AVKON_SOFTKEY_UNMARK; |
|
2704 } |
|
2705 else if ( !FocusedItem()->IsMarked() && |
|
2706 bg->CommandId( 3 ) == EAknSoftkeyUnmark ) |
|
2707 { |
|
2708 newResourceId = R_AVKON_SOFTKEY_MARK; |
|
2709 } |
|
2710 } |
|
2711 |
|
2712 if ( newResourceId ) |
|
2713 { |
|
2714 TRAP_IGNORE( bgc->SetCommandL( 3, newResourceId ) ); |
|
2715 bgc->DrawNow(); |
|
2716 } |
|
2717 } |
|
2718 } |
|
2719 |
|
2720 // --------------------------------------------------------------------------- |
|
2721 // Draws the items when physics is enabled. |
|
2722 // --------------------------------------------------------------------------- |
|
2723 // |
|
2724 void CAknTreeListView::DrawItemsWithPhysics( const TRect& aRect ) const |
|
2725 { |
|
2726 TBool empty = IsEmpty(); |
|
2727 |
|
2728 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2729 CWindowGc& gc = iGc && !empty ? *iGc : SystemGc(); |
|
2730 TInt offset = Offset(); |
|
2731 #else |
|
2732 CWindowGc& gc = SystemGc(); |
|
2733 #endif |
|
2734 |
|
2735 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2736 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &gc ); |
|
2737 if ( !empty && transApi ) |
|
2738 { |
|
2739 |
|
2740 //fix scrollbar flickering by adding nondrawingrect |
|
2741 if ( iScrollbarFrame && iScrollbarFrame->ScrollBarVisibility |
|
2742 (CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOff ) |
|
2743 { |
|
2744 //why doesn't this link? |
|
2745 //transApi->AddNonDrawingRect( iScrollbarFrame->HorizontalScrollBar()->Rect() ); |
|
2746 } |
|
2747 if ( iScrollbarFrame && iScrollbarFrame->ScrollBarVisibility |
|
2748 (CEikScrollBar::EVertical ) != CEikScrollBarFrame::EOff ) |
|
2749 { |
|
2750 transApi->ResetNonDrawingRects (); |
|
2751 transApi->AddNonDrawingRect( iScrollbarFrame->VerticalScrollBar()->Rect() ); |
|
2752 } |
|
2753 |
|
2754 transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeTreeList ); |
|
2755 transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, Rect() ); |
|
2756 transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); |
|
2757 } |
|
2758 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2759 |
|
2760 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
2761 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
2762 AknsDrawUtils::Background( skin, cc, this, gc, aRect ); |
|
2763 |
|
2764 if ( empty ) |
|
2765 { |
|
2766 __ASSERT_DEBUG( iEmptyListText, User::Invariant() ); |
|
2767 AknDrawWithSkins::DrawEmptyList( Rect(), gc, iEmptyListText->Des(), |
|
2768 const_cast<CAknTreeListView*>( this ) ); |
|
2769 } |
|
2770 else |
|
2771 { |
|
2772 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2773 if ( transApi ) |
|
2774 { |
|
2775 transApi->StopDrawing(); |
|
2776 } |
|
2777 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2778 |
|
2779 const TInt itemCount = iItems.Count(); |
|
2780 for ( TInt ii = 0; ii < itemCount; ++ii ) |
|
2781 { |
|
2782 TRect drawRect( iItems[ii].Rect() ); |
|
2783 |
|
2784 if ( iItems[ii].Item() ) |
|
2785 { |
|
2786 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2787 TRect tfxDrawRect( drawRect ); |
|
2788 tfxDrawRect.Move( 0, -offset ); |
|
2789 |
|
2790 if ( transApi ) |
|
2791 { |
|
2792 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); |
|
2793 } |
|
2794 |
|
2795 |
|
2796 TRect clippingRect( tfxDrawRect ); |
|
2797 |
|
2798 // If horizontal scrollbar on, reduce clipping rect |
|
2799 // based on view rect from layout data |
|
2800 if ( iScrollbarFrame->ScrollBarVisibility( CEikScrollBar::EHorizontal ) |
|
2801 == CEikScrollBarFrame::EOn ) |
|
2802 { |
|
2803 TRect viewRect( iPhysicsHandler->ViewRect( ) ); |
|
2804 if ( clippingRect.iBr.iY > viewRect.iBr.iY ) |
|
2805 { |
|
2806 clippingRect.iBr.iY = viewRect.iBr.iY; |
|
2807 } |
|
2808 } |
|
2809 |
|
2810 // Set clipping rect. |
|
2811 gc.SetClippingRect( clippingRect ); |
|
2812 |
|
2813 |
|
2814 if ( transApi ) |
|
2815 { |
|
2816 transApi->StopDrawing(); |
|
2817 } |
|
2818 #endif |
|
2819 TBool focused = ( IsFocused() && FocusedItem() && |
|
2820 iItems[ii].Item() == FocusedItem() ); |
|
2821 |
|
2822 if ( SingleClickEnabled() && !HighlightEnabled() ) |
|
2823 { |
|
2824 focused = EFalse; |
|
2825 } |
|
2826 |
|
2827 if ( focused ) |
|
2828 { |
|
2829 // Draw highlight for focused item. |
|
2830 TRect highlightRect( iItems[ii].HighlightRect( |
|
2831 iViewLevel, Indention(), IndentionWidth() ) ); |
|
2832 |
|
2833 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2834 TRect tfxHighlightRect( highlightRect ); |
|
2835 tfxHighlightRect.Move( 0, -offset ); |
|
2836 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2837 |
|
2838 if ( iIsPressedDownState || !DrawAnimation( gc, highlightRect ) ) |
|
2839 { |
|
2840 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2841 if ( transApi ) |
|
2842 { |
|
2843 transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight ); |
|
2844 transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, tfxHighlightRect ); |
|
2845 transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight ); |
|
2846 } |
|
2847 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2848 |
|
2849 DrawHighlight( gc, highlightRect, iIsPressedDownState ); |
|
2850 |
|
2851 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2852 if ( transApi ) |
|
2853 { |
|
2854 transApi->StopDrawing(); |
|
2855 transApi->EndRedraw(MAknListBoxTfxInternal::EListHighlight); |
|
2856 } |
|
2857 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2858 } |
|
2859 |
|
2860 drawRect.BoundingRect( highlightRect ); |
|
2861 |
|
2862 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2863 tfxDrawRect.BoundingRect( tfxHighlightRect ); |
|
2864 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2865 } |
|
2866 |
|
2867 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2868 if (iItems[ii].Item()) |
|
2869 { |
|
2870 if ( transApi ) |
|
2871 { |
|
2872 transApi->BeginRedraw(MAknListBoxTfxInternal::EListItem, tfxDrawRect, iTree.VisibleItemIndex(iItems[ii].Item())); |
|
2873 transApi->StartDrawing( MAknListBoxTfxInternal::EListItem ); |
|
2874 } |
|
2875 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2876 |
|
2877 // Draw item. |
|
2878 iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel, |
|
2879 StructureLines(), Indention(), IndentionWidth() ); |
|
2880 |
|
2881 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2882 if ( transApi ) |
|
2883 { |
|
2884 transApi->StopDrawing(); |
|
2885 transApi->EndRedraw(MAknListBoxTfxInternal::EListItem, iTree.VisibleItemIndex(iItems[ii].Item())); |
|
2886 } |
|
2887 } |
|
2888 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
2889 |
|
2890 } |
|
2891 } |
|
2892 } |
|
2893 |
|
2894 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2895 if ( !empty && transApi ) |
|
2896 { |
|
2897 transApi->EndViewRedraw( Rect() ); |
|
2898 } |
|
2899 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2900 } |
|
2901 |
|
2902 |
|
2903 // --------------------------------------------------------------------------- |
|
2904 // Returns first visible item index. |
|
2905 // --------------------------------------------------------------------------- |
|
2906 // |
|
2907 TInt CAknTreeListView::FirstVisibleItemIndex() const |
|
2908 { |
|
2909 return iPhysicsHandler->FirstVisibleItemIndex(); |
|
2910 } |
|
2911 |
|
2912 |
|
2913 // --------------------------------------------------------------------------- |
|
2914 // Returns last visible item index. |
|
2915 // --------------------------------------------------------------------------- |
|
2916 // |
|
2917 TInt CAknTreeListView::LastVisibleItemIndex() const |
|
2918 { |
|
2919 return iPhysicsHandler->LastVisibleItemIndex(); |
|
2920 } |
|
2921 |
|
2922 |
|
2923 // --------------------------------------------------------------------------- |
|
2924 // Updates view items so that aItem is visible. |
|
2925 // --------------------------------------------------------------------------- |
|
2926 // |
|
2927 void CAknTreeListView::UpdateViewItemAsVisible( CAknTreeItem* aItem ) |
|
2928 { |
|
2929 |
|
2930 // Do nothing if all items fit to view |
|
2931 if ( iItems.Count() >= iTree.VisibleItemCount() ) |
|
2932 { |
|
2933 return; |
|
2934 } |
|
2935 |
|
2936 // Items after this item |
|
2937 TInt itemsAfterVisible( |
|
2938 iTree.VisibleItemCount() - 1 - iTree.VisibleItemIndex( aItem ) ); |
|
2939 |
|
2940 CAknTreeItem* item( aItem ); |
|
2941 TAknTreeIterator iterator( iTree.Iterator() ); |
|
2942 iterator.SetCurrent( item ); |
|
2943 SetFocusIndex( KMinTInt ); |
|
2944 |
|
2945 // If there are enough items to fill the view after this item, |
|
2946 // set this item as first in the item list |
|
2947 if ( itemsAfterVisible > iItems.Count() ) |
|
2948 { |
|
2949 for ( TInt ii = 0; ii < iItems.Count(); ++ii ) |
|
2950 { |
|
2951 iItems[ii].SetItem( item ); |
|
2952 if ( item ) |
|
2953 { |
|
2954 if ( item == FocusedItem() ) |
|
2955 { |
|
2956 SetFocusIndex( ii ); |
|
2957 } |
|
2958 item = iterator.Next(); |
|
2959 } |
|
2960 } |
|
2961 } |
|
2962 |
|
2963 // Else adjust the visible items from the last item |
|
2964 else |
|
2965 { |
|
2966 item = iTree.VisibleItem( iTree.VisibleItemCount() - 1 ); |
|
2967 iterator.SetCurrent( item ); |
|
2968 for ( TInt ii = iItems.Count() - 1; ii >= 0; ii-- ) |
|
2969 { |
|
2970 iItems[ii].SetItem( item ); |
|
2971 if ( item ) |
|
2972 { |
|
2973 if ( item == FocusedItem() ) |
|
2974 { |
|
2975 SetFocusIndex( ii ); |
|
2976 } |
|
2977 item = iterator.Previous(); |
|
2978 } |
|
2979 } |
|
2980 iScrollPhysicsTop = EFalse; |
|
2981 } |
|
2982 |
|
2983 } |
|
2984 |
|
2985 |
|
2986 // --------------------------------------------------------------------------- |
|
2987 // From class CCoeControl. |
|
2988 // Draws the tree list view. |
|
2989 // --------------------------------------------------------------------------- |
|
2990 // |
|
2991 void CAknTreeListView::Draw( const TRect& aRect ) const |
|
2992 { |
|
2993 DrawItemsWithPhysics( aRect ); |
|
2994 } |
|
2995 |
|
2996 |
|
2997 // --------------------------------------------------------------------------- |
|
2998 // Enables or disables the highlight drawing |
|
2999 // --------------------------------------------------------------------------- |
|
3000 // |
|
3001 void CAknTreeListView::EnableHighlight( TBool aEnabled ) |
|
3002 { |
|
3003 if ( aEnabled ) |
|
3004 { |
|
3005 iFlags.Set( EFlagHighlightEnabled ); |
|
3006 } |
|
3007 else |
|
3008 { |
|
3009 iFlags.Clear( EFlagHighlightEnabled ); |
|
3010 } |
|
3011 } |
|
3012 |
|
3013 // --------------------------------------------------------------------------- |
|
3014 // Returns ETrue if highlight is enabled |
|
3015 // --------------------------------------------------------------------------- |
|
3016 // |
|
3017 TBool CAknTreeListView::HighlightEnabled() const |
|
3018 { |
|
3019 return iFlags.IsSet( EFlagHighlightEnabled ); |
|
3020 } |
|
3021 |
|
3022 // --------------------------------------------------------------------------- |
|
3023 // Returns ETrue if single click is enabled |
|
3024 // --------------------------------------------------------------------------- |
|
3025 // |
|
3026 TBool CAknTreeListView::SingleClickEnabled() const |
|
3027 { |
|
3028 if ( iFlags.IsSet( EFlagSingleClickEnabled ) ) |
|
3029 { |
|
3030 return ETrue; |
|
3031 } |
|
3032 return EFalse; |
|
3033 } |
|
3034 |
|
3035 // ----------------------------------------------------------------------------- |
|
3036 // CAknTreeListView::CollectionState |
|
3037 // ----------------------------------------------------------------------------- |
|
3038 // |
|
3039 TUint CAknTreeListView::CollectionState() const |
|
3040 { |
|
3041 TUint state( 0 ); |
|
3042 if ( IsVisible() ) |
|
3043 { |
|
3044 state |= MAknCollection::EStateCollectionVisible; |
|
3045 } |
|
3046 if ( HighlightEnabled() ) |
|
3047 { |
|
3048 state |= MAknCollection::EStateHighlightVisible; |
|
3049 } |
|
3050 return state; |
|
3051 } |
|
3052 |
|
3053 // ----------------------------------------------------------------------------- |
|
3054 // CAknTreeListView::ItemActionMenuClosed |
|
3055 // ----------------------------------------------------------------------------- |
|
3056 // |
|
3057 void CAknTreeListView::ItemActionMenuClosed() |
|
3058 { |
|
3059 iFlags.Clear( EFlagIgnoreButtonUpEvent ); |
|
3060 EnableHighlight( EFalse ); |
|
3061 DrawDeferred(); |
|
3062 } |
|
3063 |
|
3064 // ----------------------------------------------------------------------------- |
|
3065 // CAknTreeListView::CollectionExtension |
|
3066 // ----------------------------------------------------------------------------- |
|
3067 // |
|
3068 TInt CAknTreeListView::CollectionExtension( TUint /*aExtensionId*/, |
|
3069 TAny*& /*a0*/, TAny* /*a1*/ ) |
|
3070 { |
|
3071 return KErrNone; |
|
3072 } |
|
3073 |
|
3074 // --------------------------------------------------------------------------- |
|
3075 // CAknTreeListView::HandleLongTapEventL |
|
3076 // --------------------------------------------------------------------------- |
|
3077 // |
|
3078 void CAknTreeListView::HandleLongTapEventL( |
|
3079 const TPoint& /*aPenEventLocation*/, |
|
3080 const TPoint& aPenEventScreenLocation) |
|
3081 { |
|
3082 iFlags.Set( EFlagIgnoreButtonUpEvent ); |
|
3083 iItemActionMenu->ShowMenuL( aPenEventScreenLocation, 0 ); |
|
3084 } |
|
3085 |
|
3086 // --------------------------------------------------------------------------- |
|
3087 // CAknTreeListView::LongTapPointerEventL |
|
3088 // --------------------------------------------------------------------------- |
|
3089 // |
|
3090 void CAknTreeListView::LongTapPointerEventL( |
|
3091 const TPointerEvent& aPointerEvent) |
|
3092 { |
|
3093 if ( iLongTapDetector && iItemActionMenu && iItemActionMenu->InitMenuL() ) |
|
3094 { |
|
3095 iLongTapDetector->PointerEventL( aPointerEvent ); |
|
3096 } |
|
3097 } |
|
3098 |
|
3099 // --------------------------------------------------------------------------- |
|
3100 // CAknTreeListView::CancelLongTapDetector |
|
3101 // --------------------------------------------------------------------------- |
|
3102 // |
|
3103 void CAknTreeListView::CancelLongTapDetectorL() |
|
3104 { |
|
3105 if ( iLongTapDetector ) |
|
3106 { |
|
3107 iLongTapDetector->CancelAnimationL(); |
|
3108 } |
|
3109 } |
|
3110 |
|
3111 // --------------------------------------------------------------------------- |
|
3112 // CAknTreeListView::HasMarkedItemsL |
|
3113 // --------------------------------------------------------------------------- |
|
3114 // |
|
3115 TBool CAknTreeListView::HasMarkedItemsL() |
|
3116 { |
|
3117 RArray<TInt> selection; |
|
3118 CleanupClosePushL( selection ); |
|
3119 iList.GetMarkedItemsL( selection ); |
|
3120 TInt count( selection.Count() ); |
|
3121 CleanupStack::PopAndDestroy( &selection ); |
|
3122 if ( count > 0 ) |
|
3123 { |
|
3124 return ETrue; |
|
3125 } |
|
3126 return EFalse; |
|
3127 } |
|
3128 |
|
3129 |
|
3130 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3131 // --------------------------------------------------------------------------- |
|
3132 // Sets the tfxgc for effects |
|
3133 // --------------------------------------------------------------------------- |
|
3134 // |
|
3135 void CAknTreeListView::SetGc( CWindowGc* aGc) |
|
3136 { |
|
3137 iGc = aGc; |
|
3138 iPhysicsHandler->SetGc( aGc ); |
|
3139 } |
|
3140 |
|
3141 TInt& CAknTreeListView::ItemCountLimit( ) |
|
3142 { |
|
3143 return iItemCountLimit; |
|
3144 } |
|
3145 |
|
3146 TInt& CAknTreeListView::HighlightIndex() |
|
3147 { |
|
3148 return iHighlightIndex; |
|
3149 } |
|
3150 |
|
3151 |
|
3152 TInt& CAknTreeListView::TopIndex() |
|
3153 { |
|
3154 return iTopIndex; |
|
3155 } |
|
3156 |
|
3157 TInt& CAknTreeListView::BottomIndex() |
|
3158 { |
|
3159 return iBottomIndex; |
|
3160 } |
|
3161 |
|
3162 void CAknTreeListView::UpdateIndexes() |
|
3163 { |
|
3164 iTopIndex = iBottomIndex = iHighlightIndex = 0; |
|
3165 |
|
3166 if ( iItems.Count() ) |
|
3167 { |
|
3168 for (TInt i=iItems.Count()-1; i>=0; i--) |
|
3169 { |
|
3170 if (iItems[i].Item()) |
|
3171 { |
|
3172 iBottomIndex = iTree.VisibleItemIndex(iItems[i].Item()); |
|
3173 break; |
|
3174 } |
|
3175 } |
|
3176 |
|
3177 iTopIndex = iTree.VisibleItemIndex(iItems[0].Item()); |
|
3178 iHighlightIndex = iTree.VisibleItemIndex(FocusedItem()); |
|
3179 } |
|
3180 } |
|
3181 |
|
3182 #endif //RD_UI_TRANSITION_EFFECTS_LIST |