|
1 /* |
|
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: List box implementation. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32base.h> |
|
20 #include <e32keys.h> |
|
21 #include <bamatch.h> |
|
22 #include <badesca.h> |
|
23 #include <barsread.h> |
|
24 #include <eiklbx.h> |
|
25 #include <eiklbv.h> |
|
26 #include <eiklbi.h> |
|
27 #include <eiklbm.h> |
|
28 #include <eikenv.h> |
|
29 #include <eiklbx.pan> |
|
30 #include <gulbordr.h> |
|
31 #include <eikbutb.h> |
|
32 #include <coemain.h> |
|
33 #include <w32std.h> |
|
34 #include <gulutil.h> |
|
35 #include <uikon.hrh> |
|
36 #include <eikkeys.h> |
|
37 //#include <laflistb.h> |
|
38 #include <laflbx.h> |
|
39 |
|
40 #include <eikpanic.h> |
|
41 #include <eikcmobs.h> |
|
42 |
|
43 // Needed to use MopGetObject |
|
44 #include <coemop.h> |
|
45 #include <eikmenub.h> |
|
46 #include <AknLayout.lag> |
|
47 #include <aknenv.h> |
|
48 #include <AknDef.h> |
|
49 #include <AknUtils.h> |
|
50 |
|
51 #include <aknappui.h> |
|
52 #include <aknPopup.h> |
|
53 |
|
54 #include <AknTasHook.h> |
|
55 // For hash key marking. |
|
56 #include <e32property.h> |
|
57 #include <featmgr.h> |
|
58 #include <centralrepository.h> |
|
59 #include <cenrepnotifyhandler.h> |
|
60 #include <AknFepInternalCRKeys.h> // KAknFepHashKeySelection |
|
61 #include <AvkonInternalCRKeys.h> // KAknQwertyInputModeActive |
|
62 #include <aknlayoutscalable_avkon.cdl.h> |
|
63 #include <aknphysics.h> |
|
64 #include <aknphysicsobserveriface.h> |
|
65 |
|
66 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
67 #include <aknlistboxtfxinternal.h> // LISTBOX EFFECTS IMPLEMENTATION |
|
68 #include <aknlistloadertfx.h> |
|
69 #include <aknlistboxtfx.h> |
|
70 #endif |
|
71 |
|
72 #include <touchfeedback.h> |
|
73 #include <akncollection.h> |
|
74 #include <aknitemactionmenu.h> |
|
75 #include <aknlongtapdetector.h> |
|
76 #include <aknpriv.hrh> |
|
77 #include "akntrace.h" |
|
78 |
|
79 // timeout for long keypress used in markable lists |
|
80 const TInt KLongPressInterval = 600000; // 0,6 seconds |
|
81 const TInt KEikListBoxPointerRepeatInterval = 100000; // in micro conds (= 0.1 secod) |
|
82 |
|
83 // Maximum scroll speed ( max amount of items moved one time ) |
|
84 const TInt KDefaultMaxSpeed = 30; |
|
85 const TInt KDefaultStepSpeed = 5; |
|
86 const TInt KEikListBoxInvalidIndex=-1; |
|
87 //interval time for disable second point event |
|
88 const TInt KTwoPointerUpEventInterval = 120; // 120 millisecond ( = 0.12 second ) |
|
89 // ----------------------------------------------------------------------------- |
|
90 // If a parent to the supplied control has its Gc set, this function will find |
|
91 // it and return it. |
|
92 // ----------------------------------------------------------------------------- |
|
93 // |
|
94 LOCAL_C CWindowGc* ReplaceGcWithCustomGc( const CEikListBox* aListBox ) |
|
95 { |
|
96 _AKNTRACE_FUNC_ENTER; |
|
97 const CCoeControl* parent = aListBox; |
|
98 CWindowGc* customGc; |
|
99 while(parent) |
|
100 { |
|
101 customGc = parent->GetGc(); |
|
102 if ( customGc ) |
|
103 { |
|
104 CListItemDrawer* itemDrawer = aListBox->View()->ItemDrawer(); |
|
105 CWindowGc* originalGc = itemDrawer->Gc(); |
|
106 if ( customGc == originalGc ) |
|
107 { |
|
108 _AKNTRACE_FUNC_EXIT; |
|
109 return NULL; |
|
110 } |
|
111 else |
|
112 { |
|
113 itemDrawer->SetGc( customGc ); |
|
114 _AKNTRACE_FUNC_EXIT; |
|
115 return originalGc; |
|
116 } |
|
117 } |
|
118 parent = parent->Parent(); |
|
119 } |
|
120 _AKNTRACE_FUNC_EXIT; |
|
121 return NULL; |
|
122 } |
|
123 |
|
124 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
125 // --------------------------------------------------------------------------- |
|
126 // Helper function that selects list items |
|
127 // --------------------------------------------------------------------------- |
|
128 // |
|
129 LOCAL_C void SelectL( CListBoxView* aView, MAknListBoxTfxInternal* transApi, TInt aIndex, TBool select, TBool force = EFalse ) |
|
130 { |
|
131 _AKNTRACE_FUNC_ENTER; |
|
132 if ( aView->ItemIsSelected( aIndex ) == select ) |
|
133 { |
|
134 if ( force || transApi->SetPosition( MAknListBoxTfxInternal::EListItem, aView->ItemPos( aIndex ), aIndex ) != KErrNone ) |
|
135 { |
|
136 aView->DrawItem( aIndex ); |
|
137 } |
|
138 } |
|
139 else if ( select ) |
|
140 { |
|
141 if ( aIndex >= aView->TopItemIndex() && aIndex <= aView->BottomItemIndex() ) |
|
142 { |
|
143 aView->SelectItemL( aIndex ); |
|
144 } |
|
145 else if ( !transApi->Exist( MAknListBoxTfxInternal::EListItem, aIndex ) ) |
|
146 { |
|
147 aView->SelectItemL( aIndex ); |
|
148 } |
|
149 else |
|
150 { |
|
151 TInt topItemIndex = aView->TopItemIndex(); |
|
152 aView->SetTopItemIndex( aIndex ); |
|
153 aView->SelectItemL( aIndex ); |
|
154 aView->SetTopItemIndex( topItemIndex ); |
|
155 } |
|
156 } |
|
157 else |
|
158 { |
|
159 if ( aIndex >= aView->TopItemIndex() && aIndex <= aView->BottomItemIndex() ) |
|
160 { |
|
161 aView->DeselectItem( aIndex ); |
|
162 } |
|
163 else if ( !transApi->Exist( MAknListBoxTfxInternal::EListItem, aIndex ) ) |
|
164 { |
|
165 aView->DeselectItem( aIndex ); |
|
166 } |
|
167 else |
|
168 { |
|
169 TInt topItemIndex = aView->TopItemIndex(); |
|
170 aView->SetTopItemIndex( aIndex ); |
|
171 aView->DeselectItem( aIndex ); |
|
172 aView->SetTopItemIndex( topItemIndex ); |
|
173 } |
|
174 } |
|
175 _AKNTRACE_FUNC_EXIT; |
|
176 } |
|
177 |
|
178 // --------------------------------------------------------------------------- |
|
179 // Helper function that updates list item selections |
|
180 // --------------------------------------------------------------------------- |
|
181 // |
|
182 LOCAL_C void UpdateSelectionsL( CListBoxView* aView, MAknListBoxTfxInternal* transApi, TInt aHl, TInt aOld, TInt aAnchor, TBool aSelect ) |
|
183 { |
|
184 _AKNTRACE_FUNC_ENTER; |
|
185 if ( aHl < aOld ) |
|
186 { |
|
187 // Going up |
|
188 if ( aOld <= aAnchor ) |
|
189 { |
|
190 // Going up away |
|
191 SelectL( aView, transApi, aOld, aSelect, ETrue ); |
|
192 for ( TInt i = aOld - 1; i > aHl; i-- ) |
|
193 { |
|
194 SelectL( aView, transApi, i, aSelect ); |
|
195 } |
|
196 SelectL( aView, transApi, aHl, aSelect, ETrue ); |
|
197 } |
|
198 else if ( aHl >= aAnchor ) |
|
199 { |
|
200 // Going up against |
|
201 for ( TInt i = aOld; i > aHl; i-- ) |
|
202 { |
|
203 SelectL( aView, transApi, i, !aSelect ); |
|
204 } |
|
205 SelectL( aView, transApi, aHl, aSelect, ETrue ); |
|
206 } |
|
207 else |
|
208 { |
|
209 // Passing anchor |
|
210 for ( TInt i = aOld; i > aAnchor; i-- ) |
|
211 { |
|
212 SelectL( aView, transApi, i, !aSelect ); |
|
213 } |
|
214 for ( TInt i = aAnchor; i >= aHl; i-- ) |
|
215 { |
|
216 SelectL( aView, transApi, i, aSelect ); |
|
217 } |
|
218 } |
|
219 for ( TInt i = aView->BottomItemIndex(); i >= aView->TopItemIndex(); i-- ) |
|
220 { |
|
221 if ( i < aHl || i > aOld ) |
|
222 { |
|
223 if ( transApi->SetPosition( MAknListBoxTfxInternal::EListItem, aView->ItemPos( i ), i ) != KErrNone ) |
|
224 { |
|
225 aView->DrawItem( i ); |
|
226 } |
|
227 } |
|
228 } |
|
229 } |
|
230 else if ( aHl >= aOld ) |
|
231 { |
|
232 // Going down |
|
233 if ( aOld >= aAnchor ) |
|
234 { |
|
235 // Going down away |
|
236 SelectL( aView, transApi, aOld, aSelect, ETrue ); |
|
237 for ( TInt i = aOld + 1; i < aHl; i++ ) |
|
238 { |
|
239 SelectL( aView, transApi, i, aSelect ); |
|
240 } |
|
241 SelectL( aView, transApi, aHl, aSelect, ETrue ); |
|
242 } |
|
243 else if ( aHl <= aAnchor ) |
|
244 { |
|
245 // Going down against |
|
246 for ( TInt i = aOld; i < aHl; i++ ) |
|
247 { |
|
248 SelectL( aView, transApi, i, !aSelect ); |
|
249 } |
|
250 SelectL( aView, transApi, aHl, aSelect, ETrue ); |
|
251 } |
|
252 else |
|
253 { |
|
254 // Passing anchor |
|
255 for ( TInt i = aOld; i < aAnchor; i++ ) |
|
256 { |
|
257 SelectL( aView, transApi, i, !aSelect ); |
|
258 } |
|
259 for ( TInt i = aAnchor; i <= aHl; i++ ) |
|
260 { |
|
261 SelectL( aView, transApi, i, aSelect ); |
|
262 } |
|
263 } |
|
264 for ( TInt i = aView->BottomItemIndex(); i >= aView->TopItemIndex(); i-- ) |
|
265 { |
|
266 if ( i > aHl || i < aOld ) |
|
267 { |
|
268 if ( transApi->SetPosition( MAknListBoxTfxInternal::EListItem, aView->ItemPos( i ), i ) != KErrNone ) |
|
269 { |
|
270 aView->DrawItem( i ); |
|
271 } |
|
272 } |
|
273 } |
|
274 } |
|
275 _AKNTRACE_FUNC_EXIT; |
|
276 } |
|
277 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
278 |
|
279 // |
|
280 // class CMatchBuffer |
|
281 // |
|
282 |
|
283 NONSHARABLE_CLASS(CMatchBuffer) : public CBase |
|
284 { |
|
285 public: |
|
286 enum TExtent |
|
287 { EFull, EMinimal }; |
|
288 public: |
|
289 static CMatchBuffer* NewL(TExtent aExtent); |
|
290 ~CMatchBuffer(); |
|
291 void ConstructMatchBufferL(); |
|
292 public: |
|
293 RIncrMatcherBase* iMatchBuffer; |
|
294 TInt iPressedIndex; |
|
295 TBool iDragToAnotherItem; |
|
296 }; |
|
297 |
|
298 CMatchBuffer* CMatchBuffer::NewL(TExtent aExtent) |
|
299 { |
|
300 CMatchBuffer* buffer=new(ELeave) CMatchBuffer; |
|
301 if (aExtent==EFull) |
|
302 { |
|
303 CleanupStack::PushL(buffer); |
|
304 buffer->iMatchBuffer=new(ELeave)RIncrMatcherBuf<CEikListBox::KEikMaxMatchingBufferLength>; |
|
305 CleanupStack::Pop( buffer ); |
|
306 } |
|
307 return buffer; |
|
308 } |
|
309 |
|
310 CMatchBuffer::~CMatchBuffer() |
|
311 { |
|
312 delete iMatchBuffer; |
|
313 } |
|
314 |
|
315 void CMatchBuffer::ConstructMatchBufferL() |
|
316 { |
|
317 iMatchBuffer=new(ELeave)RIncrMatcherBuf<CEikListBox::KEikMaxMatchingBufferLength>; |
|
318 } |
|
319 |
|
320 // |
|
321 // class CLBMSKCommandObserver |
|
322 // |
|
323 |
|
324 NONSHARABLE_CLASS(CLBMSKCommandObserver) : public MEikCommandObserver |
|
325 { |
|
326 public: |
|
327 CLBMSKCommandObserver(CEikButtonGroupContainer *aCba, CEikListBox *aListBox); |
|
328 void ProcessCommandL(TInt aCommandId); |
|
329 CEikButtonGroupContainer *iCba; |
|
330 CEikListBox *iListBox; |
|
331 TInt iCurrentResource; |
|
332 }; |
|
333 |
|
334 |
|
335 CLBMSKCommandObserver::CLBMSKCommandObserver(CEikButtonGroupContainer *aCba, CEikListBox *aListBox) |
|
336 : iCba(aCba), iListBox(aListBox) |
|
337 { |
|
338 } |
|
339 |
|
340 void CLBMSKCommandObserver::ProcessCommandL(TInt aCommandId) |
|
341 { |
|
342 switch ( aCommandId ) |
|
343 { |
|
344 case EAknSoftkeyMark: |
|
345 { |
|
346 TInt index = iListBox->CurrentItemIndex(); |
|
347 iListBox->View()->SelectItemL(index); |
|
348 iCba->SetCommandL(3,R_AVKON_SOFTKEY_UNMARK); |
|
349 iCba->DrawNow(); |
|
350 iCurrentResource = R_AVKON_SOFTKEY_UNMARK; |
|
351 } |
|
352 break; |
|
353 case EAknSoftkeyUnmark: |
|
354 { |
|
355 TInt index = iListBox->CurrentItemIndex(); |
|
356 iListBox->View()->DeselectItem(index); |
|
357 iCba->SetCommandL(3,R_AVKON_SOFTKEY_MARK); |
|
358 iCba->DrawNow(); |
|
359 iCurrentResource = R_AVKON_SOFTKEY_MARK; |
|
360 } |
|
361 break; |
|
362 case EAknSoftkeyShiftMSK: |
|
363 { |
|
364 iListBox->DoShiftMSKMarkingL(); |
|
365 } |
|
366 break; |
|
367 default: |
|
368 break; |
|
369 } |
|
370 } |
|
371 |
|
372 // |
|
373 // class CListBoxExt |
|
374 // |
|
375 |
|
376 NONSHARABLE_CLASS(CListBoxExt) : public CBase, public MListVisibilityObserver, |
|
377 public MCenRepNotifyHandlerCallback, |
|
378 public MAknPhysicsObserver, |
|
379 public MAknCollection, |
|
380 public MAknLongTapDetectorCallBack |
|
381 { |
|
382 public: |
|
383 static CListBoxExt* NewL(CEikListBox& aListBox); |
|
384 ~CListBoxExt(); |
|
385 |
|
386 // new functions |
|
387 void CreateMatchBufferL(); |
|
388 void CheckCreateBufferL(); |
|
389 CMatchBuffer* Buffer() const; |
|
390 TBool IsMatchBuffer() const; |
|
391 void SetReasonForFocusLost(CEikListBox::TReasonForFocusLost aReasonForFocusLost); |
|
392 CEikListBox::TReasonForFocusLost ReasonForFocusLost() const; |
|
393 |
|
394 /// @since 3.0 |
|
395 void AddItemChangeObserverL( MListBoxItemChangeObserver* aObserver ); |
|
396 /// @since 3.0 |
|
397 TBool RemoveItemChangeObserver( MListBoxItemChangeObserver* aObserver ); |
|
398 /// @since 3.0 |
|
399 void FireItemChange(CEikListBox* aListBox); |
|
400 |
|
401 void CreateMSKObserverL(CEikButtonGroupContainer *aCba, |
|
402 CEikListBox *aListBox); |
|
403 void RemoveMSKObserver(CEikListBox *aListBox); |
|
404 |
|
405 // @since 3.2 |
|
406 void AddSelectionObserverL( MListBoxSelectionObserver* aObserver ); |
|
407 TBool RemoveSelectionObserver( MListBoxSelectionObserver* aObserver ); |
|
408 // Starts the long press timer. |
|
409 void StartLongPressTimerL(); |
|
410 TBool IsInIgnoreRect( const TPoint& aPoint ) const; |
|
411 //Tests the item needs to handle all point event or not. |
|
412 TBool IsInHandleAllPointEventArray(const TInt aIndex); |
|
413 public: // from MListVisibilityObserver |
|
414 TBool IsVisible() const; |
|
415 void SetUpdateScrollBarsColors(TBool aUpdate); |
|
416 TBool UpdateScrollBarsColors() const; |
|
417 public: // from MCenRepNotifyHandlerCallback |
|
418 void HandleNotifyInt(TUint32 aId, TInt aNewValue); |
|
419 |
|
420 public: // MAknPhysicsObserver |
|
421 virtual void ViewPositionChanged( const TPoint& aNewPosition, |
|
422 TBool aDrawNow = ETrue, |
|
423 TUint aFlags = 0 ); |
|
424 virtual void PhysicEmulationEnded(); |
|
425 virtual TPoint ViewPosition() const; |
|
426 |
|
427 // From MAknCollection |
|
428 /** |
|
429 * Returns the collection state. The state is combination of |
|
430 * flags defined in MAknCollection::TStateFlag. |
|
431 * |
|
432 * @return Collection state. |
|
433 */ |
|
434 TUint CollectionState() const; |
|
435 |
|
436 /** |
|
437 * Notifies that item action menu (CAknItemActionMenu) |
|
438 * was closed. |
|
439 */ |
|
440 void ItemActionMenuClosed(); |
|
441 |
|
442 /** |
|
443 * Extension function. |
|
444 * |
|
445 * @param aExtensionId Extension id. |
|
446 * @param a0 First extension method parameter. |
|
447 * @param a1 Second extension method parameter. |
|
448 */ |
|
449 TInt CollectionExtension( TUint aExtensionId, TAny*& a0, TAny* a1 ); |
|
450 |
|
451 // From MAknLongTapDetectorCallBack |
|
452 /** |
|
453 * Long tap detector callback |
|
454 * |
|
455 * @param aPenEventLocation Long tap event location relative to parent control. |
|
456 * @param aPenEventScreenLocation Long tap event location relative to screen. |
|
457 */ |
|
458 void HandleLongTapEventL( const TPoint& aPenEventLocation, |
|
459 const TPoint& aPenEventScreenLocation ); |
|
460 |
|
461 // New single click related methods |
|
462 /** |
|
463 * Reports collection change event. |
|
464 */ |
|
465 void ReportCollectionChangedEvent(); |
|
466 |
|
467 /** |
|
468 * Enables or disables the highlight |
|
469 * @param aEnabled ETrue to enable EFalse to disable |
|
470 * @param aPointerEnabled ETrue if highlight was enabled by pointer event. |
|
471 */ |
|
472 void EnableHighlight( TBool aEnabled, TBool aPointerEnabled = EFalse ); |
|
473 |
|
474 /** |
|
475 * Sets the highlight for the first item visible after single click |
|
476 * is disabled |
|
477 */ |
|
478 void DisableSingleClick(); |
|
479 |
|
480 /** |
|
481 * Disables item specific menu. |
|
482 */ |
|
483 void DisableItemSpecificMenu(); |
|
484 |
|
485 /** |
|
486 * Sends pointer event to long tap detector if necessary. |
|
487 * |
|
488 * @aPointerEvent Pointer event to send to long tap detector. |
|
489 */ |
|
490 void LongTapPointerEventL( const TPointerEvent& aPointerEvent ); |
|
491 |
|
492 /** |
|
493 * Cancels long tap detecting if detector is active. |
|
494 */ |
|
495 void CancelLongTapL(); |
|
496 |
|
497 /** |
|
498 * Enables highlight with key event if listbox is single click enabled. |
|
499 * |
|
500 * @param aKeyEvent Received key event. |
|
501 * @param aType Key event type. |
|
502 * @return ETrue if key should be consumed. |
|
503 */ |
|
504 TBool EnableHighlightWithKeyEventL( |
|
505 TInt aTopItemIndex, |
|
506 const TKeyEvent& aKeyEvent, |
|
507 TEventCode aType ); |
|
508 |
|
509 /** |
|
510 * Returns ETrue if list has currently marked items. |
|
511 * |
|
512 * @return ETrue if list has marked items. |
|
513 */ |
|
514 TBool MarkedItems() const; |
|
515 |
|
516 public: |
|
517 void InitPhysicsL(); |
|
518 |
|
519 /** |
|
520 * Moves the current item cursor in the specified direction. This function |
|
521 * is called by @c CEikListBox in response to user input when physics |
|
522 * is enabled. |
|
523 * |
|
524 * @return @c ETrue if the event was consumed. |
|
525 * |
|
526 * @param aCursorMovement The cursor movement to apply. |
|
527 * @param aSelectionMode The selection mode of the calling list box. |
|
528 */ |
|
529 TBool MovePhysicsCursorL(CListBoxView::TCursorMovement aCursorMovement, |
|
530 CListBoxView::TSelectionMode aSelectionMode); |
|
531 |
|
532 static TInt HighlightTimerCallback( TAny* aPtr ); |
|
533 void CheckScrollBarVisibility(); |
|
534 void StartHighlightTimer(); |
|
535 void CancelHighlightTimer(); |
|
536 TBool HighlightTimerActive() const; |
|
537 void ImmediateFeedback( TTouchLogicalFeedback aFeedback, |
|
538 TTouchFeedbackType aFeedbackType, |
|
539 const TPointerEvent& aPointerEvent ); |
|
540 TBool FeedbackEnabledOnUpEvent(); |
|
541 void SetFlickOngoing( TBool ); |
|
542 void SetPanningOngoing( TBool ); |
|
543 TBool FlickOrPanningOngoing(); |
|
544 TInt ListBottomLimit(); |
|
545 |
|
546 private: |
|
547 CListBoxExt(CEikListBox& aListBox); |
|
548 void ConstructL(); |
|
549 static TInt QwertyModeChangeNotification(TAny* aObj); |
|
550 void HandleQwertyModeChangeNotification(); |
|
551 // Callback method for long press timer. |
|
552 static TInt ReportLongPressL( TAny* aThis ); |
|
553 // Handles long press. |
|
554 void DoHandleLongPressL(); |
|
555 |
|
556 private: |
|
557 enum { |
|
558 EUpdateScrollBarsColors =0x1, |
|
559 EMSKKeyDownEventReceived = 0x2, |
|
560 EHighlightEnabledByPointer = 0x4 |
|
561 }; |
|
562 |
|
563 private: |
|
564 NONSHARABLE_CLASS(CSubscriber) : public CActive |
|
565 { |
|
566 public: |
|
567 CSubscriber(TCallBack aCallBack, RProperty& aProperty); |
|
568 ~CSubscriber(); |
|
569 |
|
570 public: // New functions |
|
571 void SubscribeL(); |
|
572 void StopSubscribe(); |
|
573 |
|
574 private: // from CActive |
|
575 void RunL(); |
|
576 void DoCancel(); |
|
577 |
|
578 private: |
|
579 TCallBack iCallBack; |
|
580 RProperty& iProperty; |
|
581 }; |
|
582 public: |
|
583 |
|
584 // The index of an item, which has received the latest pointer down event. |
|
585 // This value is used in pointer up event handling to check whether or |
|
586 // not the same item received both down and up events. |
|
587 TInt iLastDownTappedItem; |
|
588 |
|
589 TInt iEventModifiers; |
|
590 TBool iWesternVariant; |
|
591 TBool iAknFepHashKeySelection; |
|
592 TBool iQwertyMode; |
|
593 TBool iMSKObserverEnabled; |
|
594 TBool iMSKButtonGroupAlive; // status of buttongroup, which is used for MSK observer |
|
595 // these are used for shift, ctrl and hash keys in markable lists |
|
596 CPeriodic* iLongPressTimer; |
|
597 TBool iSelectionModeEnabled; |
|
598 TBool iShortHashMark; |
|
599 // Contains only references, observers not owned |
|
600 RPointerArray<MListBoxSelectionObserver> iSelectionObservers; |
|
601 // used in CEikListBox::HandlePointerEventL and |
|
602 // CEikListBox::OfferKeyEventL to enable multiselection with hash key |
|
603 TBool iShiftKeyPressed; |
|
604 // Last stuly down position |
|
605 TBool iIsDownOnItem; |
|
606 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
607 TBool iSelect; |
|
608 TInt iAnchor; |
|
609 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
610 TInt iSpeed; |
|
611 // Last pointer event pos |
|
612 TPoint iLastPoint; |
|
613 |
|
614 TInt iMaxSpeed; |
|
615 TInt iStepSpeed; |
|
616 TInt iInterval; |
|
617 CPeriodic* iHighlightTimer; |
|
618 CAknPhysics *iPhysics; |
|
619 TPoint iDragStartPosition; |
|
620 TPoint iLastPointerPos; |
|
621 TBool iBackgroundDrawingSuppressed; |
|
622 TBool iClickEventsAllowed; |
|
623 TBool iScrolling; |
|
624 TSize iViewSize; |
|
625 TSize iWorldSize; |
|
626 TBool iItemDraggingReported; |
|
627 TTime iStartTime; |
|
628 TInt iItemsInSingleLine; |
|
629 TBool iEffectsEnabled; |
|
630 |
|
631 TPoint iViewPosition; // Current view position |
|
632 TInt iSelectedIndex; |
|
633 //Array of items need to handle point event everytime. |
|
634 RArray< TInt > iMutiTappingItems; |
|
635 // To calculate twice click interval time on same item. |
|
636 TUint32 iListPointUpTime; |
|
637 TInt iLastItemIndex; |
|
638 |
|
639 // Used to disable list scrolling in certain list types. |
|
640 TBool iScrollingDisabled; |
|
641 |
|
642 // Whether or not pen down on item should be reported on highlight |
|
643 // timer callback. |
|
644 TBool iReportDelayedPenDown; |
|
645 |
|
646 // Whether or not multiselection should be done on highlight |
|
647 // timer callback. |
|
648 TBool iDelayedMultiselection; |
|
649 |
|
650 // Marking mode for multiselection lists is disabled when flicking. |
|
651 TBool iMarkingDisabled; |
|
652 |
|
653 // part of HandlePointerEventL for marking is moved to highlight timer with this flag |
|
654 TBool iMarkableListMarking; |
|
655 TBool iMarkableListShiftKeyPressed; |
|
656 TInt iMarkableListSelectionMode; |
|
657 |
|
658 // previous top item |
|
659 TInt iPrevTopItemIndex; |
|
660 // is flick stopped by down event |
|
661 TBool iFlickStopped; |
|
662 |
|
663 TTouchLogicalFeedback iFeedbackType; |
|
664 |
|
665 /** |
|
666 * Pointer to item action menu. |
|
667 * Not own. |
|
668 */ |
|
669 CAknItemActionMenu* iItemActionMenu; |
|
670 |
|
671 /** |
|
672 * Long tap detector |
|
673 */ |
|
674 CAknLongTapDetector* iLongTapDetector; |
|
675 |
|
676 /** |
|
677 * Single click mode enabled or not. |
|
678 */ |
|
679 TBool iSingleClickEnabled; |
|
680 |
|
681 /** |
|
682 * Item that opened the item action menu |
|
683 */ |
|
684 TInt iLongTappedItem; |
|
685 /** |
|
686 * Pointer event to be forwarded to the long tap detector upon |
|
687 * highlight timer completion. |
|
688 */ |
|
689 TPointerEvent iDelayedPointerDownEvent; |
|
690 |
|
691 private: |
|
692 CMatchBuffer* iBuffer; |
|
693 CEikListBox& iListBox; |
|
694 CEikListBox::TReasonForFocusLost iReasonForFocusLost; |
|
695 TInt iFlags; |
|
696 // Contains only references, observers not owned |
|
697 RPointerArray<MListBoxItemChangeObserver> iItemChangeObservers; |
|
698 |
|
699 // For hash key selection. |
|
700 CRepository* iCenRep; |
|
701 CCenRepNotifyHandler* iCenRepNotifyHandler; |
|
702 CSubscriber* iQwertyModeStatusSubscriber; |
|
703 RProperty iQwertyModeStatusProperty; |
|
704 MEikCommandObserver *iMSKCommandObserver; // this is for markable/multiselection list query |
|
705 /** |
|
706 * Pointer to the feedback object. Not owned. |
|
707 */ |
|
708 MTouchFeedback* iFeedback; |
|
709 |
|
710 /** |
|
711 * Is flick ongoing or not. |
|
712 */ |
|
713 TBool iFlickOngoing; |
|
714 |
|
715 /** |
|
716 * Is panning ongoing or not. |
|
717 */ |
|
718 TBool iPanningOngoing; |
|
719 |
|
720 /** |
|
721 * Height of the list in pixels. |
|
722 */ |
|
723 TInt iListBottomLimit; |
|
724 }; |
|
725 |
|
726 // CEikListBoxExt |
|
727 |
|
728 CListBoxExt* CListBoxExt::NewL( CEikListBox& aListBox ) |
|
729 { // static |
|
730 _AKNTRACE_FUNC_ENTER; |
|
731 CListBoxExt* self = new (ELeave) CListBoxExt( aListBox ); |
|
732 CleanupStack::PushL( self ); |
|
733 self->ConstructL(); |
|
734 CleanupStack::Pop( self ); |
|
735 _AKNTRACE_FUNC_EXIT; |
|
736 return self; |
|
737 } |
|
738 |
|
739 CListBoxExt::CListBoxExt(CEikListBox& aListBox) |
|
740 : iLastDownTappedItem(KErrNotFound), iWesternVariant(ETrue), |
|
741 iAknFepHashKeySelection(EFalse), |
|
742 iQwertyMode(EFalse), iLongPressTimer(NULL), iSelectionModeEnabled(EFalse), |
|
743 iLastPoint(0,0), iMaxSpeed( KDefaultMaxSpeed ), iStepSpeed( KDefaultStepSpeed ), |
|
744 iInterval( KEikListBoxPointerRepeatInterval ), |
|
745 iClickEventsAllowed( ETrue ), |
|
746 iWorldSize(0,0), |
|
747 iSelectedIndex( KErrNotFound ), |
|
748 iListPointUpTime(0), |
|
749 iLastItemIndex(-1), |
|
750 iItemActionMenu( NULL ), |
|
751 iLongTapDetector( NULL ), |
|
752 iSingleClickEnabled( iAvkonAppUi->IsSingleClickCompatible() ), |
|
753 iLongTappedItem( KErrNotFound ), |
|
754 iListBox(aListBox) |
|
755 { |
|
756 } |
|
757 |
|
758 CListBoxExt::~CListBoxExt() |
|
759 { |
|
760 _AKNTRACE_FUNC_ENTER; |
|
761 if ( iItemActionMenu ) |
|
762 { |
|
763 iItemActionMenu->RemoveCollection( *this ); |
|
764 } |
|
765 if ( iLongTapDetector ) |
|
766 { |
|
767 delete iLongTapDetector; |
|
768 } |
|
769 |
|
770 delete iPhysics; |
|
771 delete iHighlightTimer; |
|
772 iMutiTappingItems.Close(); |
|
773 delete iLongPressTimer; |
|
774 FeatureManager::UnInitializeLib(); |
|
775 iItemChangeObservers.Reset(); |
|
776 iSelectionObservers.Reset(); |
|
777 delete iBuffer; |
|
778 |
|
779 // Stop listening CenRep. |
|
780 if (iCenRepNotifyHandler) |
|
781 { |
|
782 iCenRepNotifyHandler->StopListening(); |
|
783 } |
|
784 delete iCenRepNotifyHandler; |
|
785 delete iCenRep; |
|
786 |
|
787 // Stop subscribe in PubSub |
|
788 if (iQwertyModeStatusSubscriber) |
|
789 { |
|
790 iQwertyModeStatusSubscriber->StopSubscribe(); |
|
791 } |
|
792 iQwertyModeStatusProperty.Close(); |
|
793 delete iQwertyModeStatusSubscriber; |
|
794 if (iMSKCommandObserver) |
|
795 { |
|
796 delete iMSKCommandObserver; |
|
797 iMSKCommandObserver = NULL; |
|
798 } |
|
799 _AKNTRACE_FUNC_EXIT; |
|
800 } |
|
801 |
|
802 void CListBoxExt::ConstructL() |
|
803 { |
|
804 _AKNTRACE_FUNC_ENTER; |
|
805 // Check the mode for hash key selection. |
|
806 // Eastern (short hash doesn't mark) == Chinese, Japanese or Vietnamese |
|
807 // Western (short hash marks) == All others. |
|
808 FeatureManager::InitializeLibL(); |
|
809 if (FeatureManager::FeatureSupported(KFeatureIdChinese) || |
|
810 FeatureManager::FeatureSupported(KFeatureIdJapanese) || |
|
811 (User::Language() & KAknLanguageMask) == ELangVietnamese) |
|
812 { |
|
813 iWesternVariant = EFalse; |
|
814 } |
|
815 |
|
816 // Start listening a CenRep key indicating whether hash key selection is active. |
|
817 TRAPD(err, iCenRep = CRepository::NewL(KCRUidAknFep)); |
|
818 if (err == KErrNone) |
|
819 { |
|
820 iCenRepNotifyHandler = CCenRepNotifyHandler::NewL(*this, |
|
821 *iCenRep, |
|
822 CCenRepNotifyHandler::EIntKey, |
|
823 KAknFepHashKeySelection); |
|
824 |
|
825 iCenRepNotifyHandler->StartListeningL(); |
|
826 iCenRep->Get(KAknFepHashKeySelection, iAknFepHashKeySelection); |
|
827 } |
|
828 |
|
829 // Start also listening qwerty mode status. Hash key selection is disabled when |
|
830 // qwerty mode is active. |
|
831 User::LeaveIfError(iQwertyModeStatusProperty.Attach(KCRUidAvkon, |
|
832 KAknQwertyInputModeActive)); |
|
833 |
|
834 iQwertyModeStatusSubscriber = new (ELeave) CSubscriber( |
|
835 TCallBack(QwertyModeChangeNotification, this), iQwertyModeStatusProperty); |
|
836 |
|
837 iQwertyModeStatusSubscriber->SubscribeL(); |
|
838 |
|
839 // Get the initial value. |
|
840 HandleQwertyModeChangeNotification(); |
|
841 |
|
842 iMSKObserverEnabled = ETrue; // By default listbox handles MSK |
|
843 iShortHashMark = EFalse; |
|
844 |
|
845 iLongPressTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
846 |
|
847 if ( CAknPhysics::FeatureEnabled() ) |
|
848 { |
|
849 iPhysics = CAknPhysics::NewL( *this, &iListBox ); |
|
850 iHighlightTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
851 } |
|
852 iItemsInSingleLine = 1; |
|
853 iFeedback = MTouchFeedback::Instance(); |
|
854 |
|
855 iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this ); |
|
856 |
|
857 if ( !( iListBox.iListBoxFlags & CEikListBox::EDisableItemSpecificMenu ) |
|
858 && iItemActionMenu ) |
|
859 { |
|
860 iLongTapDetector = CAknLongTapDetector::NewL( this ); |
|
861 } |
|
862 if ( iSingleClickEnabled ) |
|
863 { |
|
864 EnableHighlight( EFalse ); |
|
865 } |
|
866 _AKNTRACE_FUNC_EXIT; |
|
867 } |
|
868 |
|
869 |
|
870 void CListBoxExt::AddSelectionObserverL( |
|
871 MListBoxSelectionObserver* aObserver ) |
|
872 { |
|
873 _AKNTRACE_FUNC_ENTER; |
|
874 iSelectionObservers.AppendL( aObserver ); |
|
875 _AKNTRACE_FUNC_EXIT; |
|
876 } |
|
877 |
|
878 TBool CListBoxExt::RemoveSelectionObserver( |
|
879 MListBoxSelectionObserver* aObserver ) |
|
880 { |
|
881 _AKNTRACE_FUNC_ENTER; |
|
882 TInt index = iSelectionObservers.Find( aObserver ); |
|
883 if( KErrNotFound == index ) |
|
884 { |
|
885 _AKNTRACE_FUNC_EXIT; |
|
886 return EFalse; |
|
887 } |
|
888 |
|
889 iSelectionObservers.Remove( index ); |
|
890 _AKNTRACE_FUNC_EXIT; |
|
891 return ETrue; |
|
892 } |
|
893 |
|
894 TPoint CListBoxExt::ViewPosition() const |
|
895 { |
|
896 return iViewPosition; |
|
897 } |
|
898 |
|
899 |
|
900 // ----------------------------------------------------------------------------- |
|
901 // CListBoxExt::CollectionState |
|
902 // ----------------------------------------------------------------------------- |
|
903 // |
|
904 TUint CListBoxExt::CollectionState() const |
|
905 { |
|
906 _AKNTRACE_FUNC_ENTER; |
|
907 TUint state( 0 ); |
|
908 if ( iListBox.IsVisible() |
|
909 && ( !iListBox.DrawableWindow() |
|
910 || !iListBox.DrawableWindow()->IsFaded() ) ) |
|
911 { |
|
912 state |= MAknCollection::EStateCollectionVisible; |
|
913 } |
|
914 if ( iListBox.iItemDrawer ) |
|
915 { |
|
916 TInt drawerFlags( iListBox.iItemDrawer->Flags() ); |
|
917 if ( !( drawerFlags |
|
918 & CListItemDrawer::ESingleClickDisabledHighlight ) |
|
919 && !( iFlags & EHighlightEnabledByPointer ) ) |
|
920 { |
|
921 state |= MAknCollection::EStateHighlightVisible; |
|
922 } |
|
923 if ( drawerFlags & CListItemDrawer::EDisableHighlight ) |
|
924 { |
|
925 state |= MAknCollection::EStateViewOnly; |
|
926 } |
|
927 } |
|
928 if ( iListBox.iListBoxFlags & CEikListBox::EMultipleSelection ) |
|
929 { |
|
930 state |= MAknCollection::EStateMultipleSelection; |
|
931 } |
|
932 _AKNTRACE_FUNC_EXIT; |
|
933 return state; |
|
934 } |
|
935 |
|
936 |
|
937 // ----------------------------------------------------------------------------- |
|
938 // CListBoxExt::ItemActionMenuClosed |
|
939 // ----------------------------------------------------------------------------- |
|
940 // |
|
941 void CListBoxExt::ItemActionMenuClosed() |
|
942 { |
|
943 if ( iLongTappedItem != KErrNotFound ) |
|
944 { |
|
945 EnableHighlight( EFalse ); |
|
946 iListBox.iView->DrawItem( iLongTappedItem ); |
|
947 iLongTappedItem = KErrNotFound; |
|
948 } |
|
949 } |
|
950 |
|
951 |
|
952 // ----------------------------------------------------------------------------- |
|
953 // CListBoxExt::CollectionExtension |
|
954 // ----------------------------------------------------------------------------- |
|
955 // |
|
956 TInt CListBoxExt::CollectionExtension( |
|
957 TUint /*aExtensionId*/, TAny*& /*a0*/, TAny* /*a1*/ ) |
|
958 { |
|
959 return KErrNone; |
|
960 } |
|
961 |
|
962 |
|
963 // --------------------------------------------------------------------------- |
|
964 // CListBoxExt::HandleLongTapEventL |
|
965 // --------------------------------------------------------------------------- |
|
966 // |
|
967 void CListBoxExt::HandleLongTapEventL( const TPoint& /*aPenEventLocation*/, |
|
968 const TPoint& aPenEventScreenLocation ) |
|
969 { |
|
970 _AKNTRACE_FUNC_ENTER; |
|
971 iLongTappedItem = iLastDownTappedItem; |
|
972 iLastDownTappedItem = KErrNotFound; |
|
973 iItemActionMenu->ShowMenuL( aPenEventScreenLocation, 0 ); |
|
974 _AKNTRACE_FUNC_EXIT; |
|
975 } |
|
976 |
|
977 |
|
978 // ----------------------------------------------------------------------------- |
|
979 // CListBoxExt::ReportCollectionChangedEvent |
|
980 // ----------------------------------------------------------------------------- |
|
981 // |
|
982 void CListBoxExt::ReportCollectionChangedEvent() |
|
983 { |
|
984 if ( iItemActionMenu ) |
|
985 { |
|
986 iItemActionMenu->CollectionChanged( *this ); |
|
987 } |
|
988 } |
|
989 |
|
990 |
|
991 // ----------------------------------------------------------------------------- |
|
992 // CListBoxExt::EnableHighLight |
|
993 // ----------------------------------------------------------------------------- |
|
994 // |
|
995 void CListBoxExt::EnableHighlight( TBool aEnabled, TBool aPointerEnabled ) |
|
996 { |
|
997 _AKNTRACE_FUNC_ENTER; |
|
998 if ( iListBox.iItemDrawer && iSingleClickEnabled ) |
|
999 { |
|
1000 TBool wasEnabled( !( iListBox.iItemDrawer->Flags() |
|
1001 & CListItemDrawer::ESingleClickDisabledHighlight ) ); |
|
1002 iFlags &= ( ~EHighlightEnabledByPointer ); |
|
1003 if ( aEnabled ) |
|
1004 { |
|
1005 iListBox.iItemDrawer->ClearFlags( |
|
1006 CListItemDrawer::ESingleClickDisabledHighlight ); |
|
1007 if ( aPointerEnabled ) |
|
1008 { |
|
1009 iFlags |= EHighlightEnabledByPointer; |
|
1010 } |
|
1011 } |
|
1012 else |
|
1013 { |
|
1014 iListBox.iItemDrawer->SetFlags( |
|
1015 CListItemDrawer::ESingleClickDisabledHighlight ); |
|
1016 } |
|
1017 if ( !aPointerEnabled |
|
1018 && ( ( wasEnabled && !aEnabled ) |
|
1019 || ( !wasEnabled && aEnabled ) ) ) |
|
1020 { |
|
1021 ReportCollectionChangedEvent(); |
|
1022 } |
|
1023 } |
|
1024 _AKNTRACE_FUNC_EXIT; |
|
1025 } |
|
1026 |
|
1027 // ----------------------------------------------------------------------------- |
|
1028 // CListBoxExt::DisableSingleClick |
|
1029 // ----------------------------------------------------------------------------- |
|
1030 // |
|
1031 void CListBoxExt::DisableSingleClick() |
|
1032 { |
|
1033 _AKNTRACE_FUNC_ENTER; |
|
1034 EnableHighlight( ETrue ); |
|
1035 |
|
1036 if ( iListBox.iView->ViewRect() != TRect() ) |
|
1037 { |
|
1038 TInt topItemIndex = iListBox.iView->TopItemIndex(); |
|
1039 if ( iListBox.iView->ItemIsPartiallyVisible( topItemIndex) ) |
|
1040 { |
|
1041 topItemIndex++; |
|
1042 } |
|
1043 TRAP_IGNORE( iListBox.UpdateHighlightL( topItemIndex ) ); |
|
1044 } |
|
1045 |
|
1046 DisableItemSpecificMenu(); |
|
1047 if ( iItemActionMenu ) |
|
1048 { |
|
1049 iItemActionMenu->RemoveCollection( *this ); |
|
1050 iItemActionMenu = NULL; |
|
1051 } |
|
1052 iSingleClickEnabled = EFalse; |
|
1053 |
|
1054 _AKNTRACE_FUNC_EXIT; |
|
1055 } |
|
1056 |
|
1057 |
|
1058 // ----------------------------------------------------------------------------- |
|
1059 // CListBoxExt::DisableItemSpecificMenu |
|
1060 // ----------------------------------------------------------------------------- |
|
1061 // |
|
1062 void CListBoxExt::DisableItemSpecificMenu() |
|
1063 { |
|
1064 _AKNTRACE_FUNC_ENTER; |
|
1065 |
|
1066 delete iLongTapDetector; |
|
1067 iLongTapDetector = NULL; |
|
1068 |
|
1069 iListBox.iListBoxFlags |= CEikListBox::EDisableItemSpecificMenu; |
|
1070 |
|
1071 _AKNTRACE_FUNC_EXIT; |
|
1072 } |
|
1073 |
|
1074 // ----------------------------------------------------------------------------- |
|
1075 // CListBoxExt::LongTapPointerEventL |
|
1076 // ----------------------------------------------------------------------------- |
|
1077 // |
|
1078 void CListBoxExt::LongTapPointerEventL( const TPointerEvent& aPointerEvent ) |
|
1079 { |
|
1080 if ( iSingleClickEnabled && iLongTapDetector && iItemActionMenu ) |
|
1081 { |
|
1082 // Send event on down only if no marked items and item specific items |
|
1083 // were found |
|
1084 if ( aPointerEvent.iType != TPointerEvent::EButton1Down |
|
1085 || ( !MarkedItems() && iItemActionMenu->InitMenuL() ) ) |
|
1086 { |
|
1087 iLongTapDetector->PointerEventL ( aPointerEvent ); |
|
1088 } |
|
1089 } |
|
1090 } |
|
1091 |
|
1092 |
|
1093 // ----------------------------------------------------------------------------- |
|
1094 // CListBoxExt::CancelLongTapL |
|
1095 // ----------------------------------------------------------------------------- |
|
1096 // |
|
1097 void CListBoxExt::CancelLongTapL() |
|
1098 { |
|
1099 if ( iLongTapDetector && iLongTapDetector->IsActive() ) |
|
1100 { |
|
1101 iLongTapDetector->CancelAnimationL(); |
|
1102 } |
|
1103 } |
|
1104 |
|
1105 |
|
1106 // ----------------------------------------------------------------------------- |
|
1107 // CListBoxExt::EnableHighlightWithKeyEventL |
|
1108 // ----------------------------------------------------------------------------- |
|
1109 // |
|
1110 TBool CListBoxExt::EnableHighlightWithKeyEventL( |
|
1111 TInt aTopItemIndex, |
|
1112 const TKeyEvent& aKeyEvent, |
|
1113 TEventCode aType ) |
|
1114 { |
|
1115 _AKNTRACE_FUNC_ENTER; |
|
1116 _AKNTRACE( "aTopItemIndex is %d", aTopItemIndex ); |
|
1117 _AKNTRACE( "aKeyEvent.iCode is %d", aKeyEvent.iCode ); |
|
1118 _AKNTRACE( "aType is %d", aType ); |
|
1119 TBool consumeKey( EFalse ); |
|
1120 // With single click first key event enables highlight |
|
1121 if ( iListBox.iItemDrawer->Flags() |
|
1122 & CListItemDrawer::ESingleClickDisabledHighlight |
|
1123 && iSingleClickEnabled ) |
|
1124 { |
|
1125 TBool enableHighlight( EFalse ); |
|
1126 // Normal case: up, down, enter, msk pressed |
|
1127 if ( aKeyEvent.iCode == EKeyUpArrow |
|
1128 || aKeyEvent.iCode == EKeyDownArrow |
|
1129 || aKeyEvent.iCode == EKeyEnter |
|
1130 || aKeyEvent.iCode == EKeyOK ) |
|
1131 { |
|
1132 consumeKey = ETrue; |
|
1133 enableHighlight = ETrue; |
|
1134 } |
|
1135 else if ( aType == EEventKeyDown |
|
1136 && aKeyEvent.iScanCode == EStdKeyDevice3 ) |
|
1137 { |
|
1138 iFlags |= EMSKKeyDownEventReceived; |
|
1139 } |
|
1140 // Msk pressed when MSK not visible |
|
1141 else if ( iFlags & EMSKKeyDownEventReceived |
|
1142 && aType == EEventKeyUp |
|
1143 && aKeyEvent.iScanCode == EStdKeyDevice3 ) |
|
1144 { |
|
1145 iFlags &= ( ~EMSKKeyDownEventReceived ); |
|
1146 enableHighlight = ETrue; |
|
1147 } |
|
1148 // Handle also left and right when grid in use. |
|
1149 else if ( iItemsInSingleLine > 1 |
|
1150 && ( aKeyEvent.iCode == EKeyLeftArrow |
|
1151 || aKeyEvent.iCode == EKeyRightArrow ) ) |
|
1152 { |
|
1153 consumeKey = ETrue; |
|
1154 enableHighlight = ETrue; |
|
1155 } |
|
1156 if ( enableHighlight ) |
|
1157 { |
|
1158 if ( iListBox.iView->ItemIsPartiallyVisible( aTopItemIndex ) ) |
|
1159 { |
|
1160 aTopItemIndex++; |
|
1161 } |
|
1162 // Enable marquee |
|
1163 if ( iListBox.iItemDrawer->Flags() |
|
1164 & CListItemDrawer::EDisableMarquee ) |
|
1165 { |
|
1166 iListBox.iItemDrawer-> |
|
1167 ClearFlags( CListItemDrawer::EDisableMarquee ); |
|
1168 } |
|
1169 EnableHighlight( ETrue ); |
|
1170 iListBox.UpdateHighlightL( aTopItemIndex ); |
|
1171 } |
|
1172 } |
|
1173 _AKNTRACE_FUNC_EXIT; |
|
1174 return consumeKey; |
|
1175 } |
|
1176 |
|
1177 |
|
1178 // ----------------------------------------------------------------------------- |
|
1179 // CListBoxExt::MarkedItems |
|
1180 // ----------------------------------------------------------------------------- |
|
1181 // |
|
1182 TBool CListBoxExt::MarkedItems() const |
|
1183 { |
|
1184 return ( iListBox.iListBoxFlags & CEikListBox::ES60StyleMarkable |
|
1185 || iListBox.iListBoxFlags & CEikListBox::EMultipleSelection ) |
|
1186 && iListBox.SelectionIndexes()->Count() > 0; |
|
1187 } |
|
1188 |
|
1189 |
|
1190 // ----------------------------------------------------------------------------- |
|
1191 // CListBoxExt::StartLongPressTimerL |
|
1192 // ----------------------------------------------------------------------------- |
|
1193 // |
|
1194 void CListBoxExt::StartLongPressTimerL() |
|
1195 { |
|
1196 _AKNTRACE_FUNC_ENTER; |
|
1197 if ( iLongPressTimer ) |
|
1198 { |
|
1199 if ( iLongPressTimer->IsActive() ) |
|
1200 { |
|
1201 iLongPressTimer->Cancel(); |
|
1202 } |
|
1203 |
|
1204 iLongPressTimer->Start( KLongPressInterval, KLongPressInterval, |
|
1205 TCallBack( ReportLongPressL, this ) ); |
|
1206 } |
|
1207 _AKNTRACE_FUNC_EXIT; |
|
1208 } |
|
1209 |
|
1210 // ----------------------------------------------------------------------------- |
|
1211 // CListBoxExt::ReportLongPressL |
|
1212 // ----------------------------------------------------------------------------- |
|
1213 // |
|
1214 TInt CListBoxExt::ReportLongPressL( TAny* aThis ) |
|
1215 { |
|
1216 _AKNTRACE_FUNC_ENTER; |
|
1217 static_cast<CListBoxExt*>( aThis )->DoHandleLongPressL(); |
|
1218 _AKNTRACE_FUNC_EXIT; |
|
1219 return 0; |
|
1220 } |
|
1221 |
|
1222 TBool CListBoxExt::IsInIgnoreRect( const TPoint& aPoint ) const |
|
1223 { |
|
1224 TInt offset = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW / 5; |
|
1225 TRect rect( iLastPoint.iX - offset, iLastPoint.iY - offset, |
|
1226 iLastPoint.iX + offset, iLastPoint.iY + offset ); |
|
1227 return rect.Contains( aPoint ); |
|
1228 } |
|
1229 |
|
1230 TBool CListBoxExt::IsInHandleAllPointEventArray(const TInt aIndex) |
|
1231 { |
|
1232 return iMutiTappingItems.FindInOrder( aIndex ) != KErrNotFound; |
|
1233 } |
|
1234 |
|
1235 // ----------------------------------------------------------------------------- |
|
1236 // CListBoxExt::DoHandleLongPressL |
|
1237 // ----------------------------------------------------------------------------- |
|
1238 // |
|
1239 void CListBoxExt::DoHandleLongPressL() |
|
1240 { |
|
1241 _AKNTRACE_FUNC_ENTER; |
|
1242 iSelectionModeEnabled = ETrue; |
|
1243 if ( iLongPressTimer && iLongPressTimer->IsActive() ) |
|
1244 { |
|
1245 iLongPressTimer->Cancel(); |
|
1246 } |
|
1247 iListBox.ChangeSelectionMode( ETrue ); |
|
1248 _AKNTRACE_FUNC_EXIT; |
|
1249 } |
|
1250 |
|
1251 |
|
1252 void CListBoxExt::CheckCreateBufferL() |
|
1253 { |
|
1254 if (!iBuffer) |
|
1255 iBuffer=CMatchBuffer::NewL(CMatchBuffer::EMinimal); |
|
1256 } |
|
1257 |
|
1258 CMatchBuffer* CListBoxExt::Buffer() const |
|
1259 { |
|
1260 return iBuffer; |
|
1261 } |
|
1262 |
|
1263 void CListBoxExt::CreateMatchBufferL() |
|
1264 { |
|
1265 _AKNTRACE_FUNC_ENTER; |
|
1266 if (iBuffer==NULL) |
|
1267 iBuffer=CMatchBuffer::NewL(CMatchBuffer::EFull); |
|
1268 else if (iBuffer->iMatchBuffer==NULL) |
|
1269 iBuffer->ConstructMatchBufferL(); |
|
1270 _AKNTRACE_FUNC_EXIT; |
|
1271 } |
|
1272 |
|
1273 TBool CListBoxExt::IsVisible() const |
|
1274 { |
|
1275 return iListBox.IsVisible(); |
|
1276 } |
|
1277 |
|
1278 TBool CListBoxExt::IsMatchBuffer() const |
|
1279 { |
|
1280 return (iBuffer && iBuffer->iMatchBuffer); |
|
1281 } |
|
1282 |
|
1283 void CListBoxExt::SetReasonForFocusLost(CEikListBox::TReasonForFocusLost aReasonForFocusLost) |
|
1284 { |
|
1285 iReasonForFocusLost = aReasonForFocusLost; |
|
1286 } |
|
1287 |
|
1288 TInt CListBoxExt::QwertyModeChangeNotification(TAny* aObj) |
|
1289 { |
|
1290 _AKNTRACE_FUNC_ENTER; |
|
1291 if (aObj != NULL) |
|
1292 { |
|
1293 static_cast<CListBoxExt*>(aObj)->HandleQwertyModeChangeNotification(); |
|
1294 _AKNTRACE_FUNC_EXIT; |
|
1295 return KErrNone; |
|
1296 } |
|
1297 else |
|
1298 { |
|
1299 _AKNTRACE_FUNC_EXIT; |
|
1300 return KErrArgument; |
|
1301 } |
|
1302 } |
|
1303 |
|
1304 void CListBoxExt::HandleQwertyModeChangeNotification() |
|
1305 { |
|
1306 TInt value = 0; |
|
1307 iQwertyModeStatusProperty.Get(value); |
|
1308 iQwertyMode = value; |
|
1309 } |
|
1310 |
|
1311 |
|
1312 void CListBoxExt::CreateMSKObserverL(CEikButtonGroupContainer *aCba, CEikListBox *aListBox) |
|
1313 { |
|
1314 _AKNTRACE_FUNC_ENTER; |
|
1315 RemoveMSKObserver(aListBox); // only one observer can be set at a time |
|
1316 iMSKCommandObserver = new(ELeave)CLBMSKCommandObserver(aCba, aListBox); |
|
1317 iMSKButtonGroupAlive = ETrue; |
|
1318 // if UpdateMSKCommandOpserver fails (there already is MSK observer set), |
|
1319 // iMSKButtonGroupAlive will be set EFalse |
|
1320 aCba->UpdateMSKCommandObserver(aListBox, iMSKCommandObserver); |
|
1321 _AKNTRACE_FUNC_EXIT; |
|
1322 } |
|
1323 |
|
1324 void CListBoxExt::RemoveMSKObserver(CEikListBox *aListBox) |
|
1325 { |
|
1326 _AKNTRACE_FUNC_ENTER; |
|
1327 if (iMSKCommandObserver) |
|
1328 { |
|
1329 if (iMSKButtonGroupAlive) |
|
1330 { |
|
1331 STATIC_CAST(CLBMSKCommandObserver*,iMSKCommandObserver)->iCba->UpdateMSKCommandObserver(aListBox, NULL); |
|
1332 } |
|
1333 delete iMSKCommandObserver; |
|
1334 iMSKCommandObserver = NULL; |
|
1335 } |
|
1336 _AKNTRACE_FUNC_EXIT; |
|
1337 } |
|
1338 |
|
1339 |
|
1340 // CEikListBoxExt::CSubscriber |
|
1341 |
|
1342 CListBoxExt::CSubscriber::CSubscriber(TCallBack aCallBack, RProperty& aProperty) |
|
1343 : CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty) |
|
1344 { |
|
1345 CActiveScheduler::Add(this); |
|
1346 } |
|
1347 |
|
1348 CListBoxExt::CSubscriber::~CSubscriber() |
|
1349 { |
|
1350 Cancel(); |
|
1351 } |
|
1352 |
|
1353 void CListBoxExt::CSubscriber::SubscribeL() |
|
1354 { |
|
1355 if (!IsActive()) |
|
1356 { |
|
1357 iProperty.Subscribe(iStatus); |
|
1358 SetActive(); |
|
1359 } |
|
1360 } |
|
1361 |
|
1362 void CListBoxExt::CSubscriber::StopSubscribe() |
|
1363 { |
|
1364 Cancel(); |
|
1365 } |
|
1366 |
|
1367 void CListBoxExt::CSubscriber::RunL() |
|
1368 { |
|
1369 if (iStatus.Int() == KErrNone) |
|
1370 { |
|
1371 iCallBack.CallBack(); |
|
1372 SubscribeL(); |
|
1373 } |
|
1374 } |
|
1375 |
|
1376 void CListBoxExt::CSubscriber::DoCancel() |
|
1377 { |
|
1378 iProperty.Cancel(); |
|
1379 } |
|
1380 |
|
1381 // CEikListBox |
|
1382 |
|
1383 CEikListBox::TReasonForFocusLost CListBoxExt::ReasonForFocusLost() const |
|
1384 { |
|
1385 return iReasonForFocusLost; |
|
1386 } |
|
1387 |
|
1388 void CListBoxExt::AddItemChangeObserverL( |
|
1389 MListBoxItemChangeObserver* aObserver ) |
|
1390 { |
|
1391 iItemChangeObservers.AppendL( aObserver ); |
|
1392 } |
|
1393 |
|
1394 TBool CListBoxExt::RemoveItemChangeObserver( |
|
1395 MListBoxItemChangeObserver* aObserver ) |
|
1396 { |
|
1397 TInt index = iItemChangeObservers.Find( aObserver ); |
|
1398 if( KErrNotFound == index ) |
|
1399 { |
|
1400 return EFalse; |
|
1401 } |
|
1402 |
|
1403 iItemChangeObservers.Remove( index ); |
|
1404 return ETrue; |
|
1405 } |
|
1406 |
|
1407 void CListBoxExt::FireItemChange(CEikListBox* aListBox) |
|
1408 { |
|
1409 TInt count = iItemChangeObservers.Count(); |
|
1410 for( int i=0; i < count; i++ ) |
|
1411 { |
|
1412 iItemChangeObservers[i]->ListBoxItemsChanged(aListBox); |
|
1413 } |
|
1414 } |
|
1415 |
|
1416 void CListBoxExt::SetUpdateScrollBarsColors(TBool aUpdate) |
|
1417 { |
|
1418 if (aUpdate) |
|
1419 iFlags |= EUpdateScrollBarsColors; |
|
1420 else |
|
1421 iFlags &= ~EUpdateScrollBarsColors; |
|
1422 } |
|
1423 |
|
1424 TBool CListBoxExt::UpdateScrollBarsColors() const |
|
1425 { |
|
1426 return (iFlags&EUpdateScrollBarsColors); |
|
1427 } |
|
1428 |
|
1429 void CListBoxExt::CheckScrollBarVisibility() |
|
1430 { |
|
1431 // Kinetic scrolling is disabled if scrollbar is not visible |
|
1432 if ( iListBox.iSBFrame ) |
|
1433 { |
|
1434 TBool allowScrolling( iListBox.iSBFrame->ScrollBarVisibility( |
|
1435 CEikScrollBar::EVertical ) != CEikScrollBarFrame::EOff ); |
|
1436 |
|
1437 iScrollingDisabled = !allowScrolling; |
|
1438 } |
|
1439 } |
|
1440 |
|
1441 void CListBoxExt::HandleNotifyInt(TUint32 aId, TInt aNewValue) |
|
1442 { |
|
1443 if (aId == KAknFepHashKeySelection) |
|
1444 { |
|
1445 iAknFepHashKeySelection = (TBool)aNewValue; |
|
1446 } |
|
1447 } |
|
1448 |
|
1449 |
|
1450 // --------------------------------------------------------------------------- |
|
1451 // Static callback function for the highlight timer. This should draw |
|
1452 // the highlight to the correct item and send the pen down event to the |
|
1453 // listbox observer. |
|
1454 // --------------------------------------------------------------------------- |
|
1455 // |
|
1456 TInt CListBoxExt::HighlightTimerCallback( TAny* aPtr ) |
|
1457 { |
|
1458 _AKNTRACE_FUNC_ENTER; |
|
1459 CListBoxExt* me = static_cast<CListBoxExt*>( aPtr ); |
|
1460 |
|
1461 if ( me ) |
|
1462 { |
|
1463 if ( me->iSingleClickEnabled ) |
|
1464 { |
|
1465 me->EnableHighlight( ETrue, ETrue ); |
|
1466 } |
|
1467 |
|
1468 TRAP_IGNORE( me->iListBox.UpdateHighlightL( |
|
1469 me->iLastDownTappedItem ) ); |
|
1470 |
|
1471 me->ImmediateFeedback( me->iFeedbackType, |
|
1472 TTouchFeedbackType(ETouchFeedbackVibra | ETouchFeedbackAudio), |
|
1473 TPointerEvent() ); |
|
1474 |
|
1475 me->CancelHighlightTimer(); |
|
1476 } |
|
1477 _AKNTRACE_FUNC_EXIT; |
|
1478 return 0; |
|
1479 } |
|
1480 |
|
1481 |
|
1482 // --------------------------------------------------------------------------- |
|
1483 // Starts the highlight timer. |
|
1484 // --------------------------------------------------------------------------- |
|
1485 // |
|
1486 void CListBoxExt::StartHighlightTimer() |
|
1487 { |
|
1488 _AKNTRACE_FUNC_ENTER; |
|
1489 CancelHighlightTimer(); |
|
1490 |
|
1491 TTimeIntervalMicroSeconds32 timeout( |
|
1492 iPhysics->HighlightTimeout() * 1000 ); |
|
1493 iHighlightTimer->Start( |
|
1494 timeout, |
|
1495 timeout, |
|
1496 TCallBack( CListBoxExt::HighlightTimerCallback, this ) ); |
|
1497 _AKNTRACE_FUNC_EXIT; |
|
1498 } |
|
1499 |
|
1500 |
|
1501 // --------------------------------------------------------------------------- |
|
1502 // Cancels the highlight timer and the delayed functions to be run upon |
|
1503 // its completion. |
|
1504 // --------------------------------------------------------------------------- |
|
1505 // |
|
1506 void CListBoxExt::CancelHighlightTimer() |
|
1507 { |
|
1508 _AKNTRACE_FUNC_ENTER; |
|
1509 if ( iHighlightTimer ) |
|
1510 { |
|
1511 iHighlightTimer->Cancel(); |
|
1512 } |
|
1513 iReportDelayedPenDown = EFalse; |
|
1514 iDelayedMultiselection = EFalse; |
|
1515 _AKNTRACE_FUNC_EXIT; |
|
1516 } |
|
1517 |
|
1518 |
|
1519 // --------------------------------------------------------------------------- |
|
1520 // Checks if the highlight timer is currently running. |
|
1521 // --------------------------------------------------------------------------- |
|
1522 // |
|
1523 TBool CListBoxExt::HighlightTimerActive() const |
|
1524 { |
|
1525 _AKNTRACE_FUNC_ENTER; |
|
1526 _AKNTRACE_FUNC_EXIT; |
|
1527 return ( iHighlightTimer && iHighlightTimer->IsActive() ); |
|
1528 } |
|
1529 |
|
1530 |
|
1531 // --------------------------------------------------------------------------- |
|
1532 // CListBoxExt::ViewPositionChanged |
|
1533 // --------------------------------------------------------------------------- |
|
1534 // |
|
1535 void CListBoxExt::ViewPositionChanged( const TPoint& aNewPosition, |
|
1536 TBool aDrawNow, |
|
1537 TUint /*aFlags*/ ) |
|
1538 { |
|
1539 _AKNTRACE_FUNC_ENTER; |
|
1540 TInt delta = iViewPosition.iY - aNewPosition.iY; |
|
1541 |
|
1542 #ifdef _DEBUG |
|
1543 _LIT( KDMsg, "CListBoxExt::ViewPositionChanged, delta = %d, aDrawNow = %d" ); |
|
1544 RDebug::Print( KDMsg, delta, aDrawNow ); |
|
1545 #endif // _DEBUG |
|
1546 |
|
1547 iListBox.ScrollView( delta, aDrawNow ); |
|
1548 iViewPosition = aNewPosition; |
|
1549 _AKNTRACE_FUNC_EXIT; |
|
1550 } |
|
1551 |
|
1552 |
|
1553 // --------------------------------------------------------------------------- |
|
1554 // CListBoxExt::PhysicEmulationEnded |
|
1555 // --------------------------------------------------------------------------- |
|
1556 // |
|
1557 void CListBoxExt::PhysicEmulationEnded() |
|
1558 { |
|
1559 _AKNTRACE_FUNC_ENTER; |
|
1560 if ( iScrolling ) |
|
1561 { |
|
1562 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1563 iListBox.SuspendEffects( EFalse ); |
|
1564 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
1565 TRAP_IGNORE( iListBox.ReportListBoxEventL( |
|
1566 MEikListBoxObserver::EEventFlickStopped ) ); |
|
1567 } |
|
1568 |
|
1569 iScrolling = EFalse; |
|
1570 iListBox.iView->SetScrolling( iScrolling ); |
|
1571 _AKNTRACE_FUNC_EXIT; |
|
1572 } |
|
1573 |
|
1574 |
|
1575 // --------------------------------------------------------------------------- |
|
1576 // CListBoxExt::InitPhysicsL |
|
1577 // --------------------------------------------------------------------------- |
|
1578 // |
|
1579 void CListBoxExt::InitPhysicsL() |
|
1580 { |
|
1581 _AKNTRACE_FUNC_ENTER; |
|
1582 if ( iPhysics ) |
|
1583 { |
|
1584 // calculate view center based on CEikListBoxView::iTopItemIndex |
|
1585 TInt topItemIndex = iListBox.iView->TopItemIndex(); |
|
1586 TInt itemHeight = iListBox.iView->ItemHeight(); |
|
1587 TInt numberOfItems = iListBox.iModel->NumberOfItems(); |
|
1588 |
|
1589 TSize viewSize( iListBox.iView->ViewRect().Size() ); |
|
1590 TSize worldSize( viewSize.iWidth, itemHeight * numberOfItems ); |
|
1591 |
|
1592 // grid has several items in one line |
|
1593 if ( iItemsInSingleLine > 1 ) |
|
1594 { |
|
1595 worldSize.iHeight = |
|
1596 itemHeight * ( numberOfItems / iItemsInSingleLine ); |
|
1597 |
|
1598 // handle non-full grid row |
|
1599 if ( numberOfItems % iItemsInSingleLine ) |
|
1600 { |
|
1601 worldSize.iHeight += itemHeight; |
|
1602 } |
|
1603 } |
|
1604 |
|
1605 // Reset offset if view's size has changed - this is needed if e.g. |
|
1606 // HandleResourceChange is overridden by a derived implementation. |
|
1607 if ( viewSize != iViewSize && iViewSize != TSize( 0, 0 ) ) |
|
1608 { |
|
1609 iListBox.iView->SetItemOffsetInPixels( 0 ); |
|
1610 } |
|
1611 |
|
1612 TPoint viewCenter( viewSize.iWidth / 2, ( topItemIndex / iItemsInSingleLine ) * itemHeight - iListBox.iView->ItemOffsetInPixels() + ( viewSize.iHeight / 2 ) ); |
|
1613 |
|
1614 // Make sure that world's size is always at least view size. |
|
1615 worldSize.iHeight = Max( worldSize.iHeight, viewSize.iHeight ); |
|
1616 |
|
1617 iPhysics->InitPhysicsL( worldSize, viewSize, EFalse ); |
|
1618 |
|
1619 iWorldSize = worldSize; |
|
1620 iViewSize = viewSize; |
|
1621 iViewPosition = viewCenter; |
|
1622 |
|
1623 #ifdef _DEBUG |
|
1624 RDebug::Print( _L( "CListBox::InitPhysicsL, iViewSize = %d, %d" ), iViewSize.iWidth, iViewSize.iHeight ); |
|
1625 RDebug::Print( _L( "CListBox::InitPhysicsL, iViewPosition = %d, %d" ), iViewPosition.iX, iViewPosition.iY ); |
|
1626 RDebug::Print( _L( "CListBox::InitPhysicsL, verticalOffset = %d" ), iListBox.iView->ItemOffsetInPixels() ); |
|
1627 #endif // _DEBUG |
|
1628 iPrevTopItemIndex = iListBox.iView->TopItemIndex(); |
|
1629 iListBottomLimit = worldSize.iHeight; |
|
1630 } |
|
1631 _AKNTRACE_FUNC_EXIT; |
|
1632 } |
|
1633 |
|
1634 // --------------------------------------------------------------------------- |
|
1635 // CListBoxExt::MovePhysicsCursorL |
|
1636 // --------------------------------------------------------------------------- |
|
1637 // |
|
1638 TBool CListBoxExt::MovePhysicsCursorL(CListBoxView::TCursorMovement aCursorMovement, |
|
1639 CListBoxView::TSelectionMode aSelectionMode) |
|
1640 { |
|
1641 _AKNTRACE_FUNC_ENTER; |
|
1642 _AKNTRACE( "aCursorMovement = %d, aSelectionMode = %d", |
|
1643 aCursorMovement, aSelectionMode ); |
|
1644 if ( !iPhysics || iScrollingDisabled ) |
|
1645 { |
|
1646 _AKNTRACE_FUNC_EXIT; |
|
1647 return EFalse; |
|
1648 } |
|
1649 |
|
1650 InitPhysicsL(); |
|
1651 TInt curViewPosY = iViewPosition.iY; |
|
1652 TInt worldHeight = iWorldSize.iHeight; |
|
1653 TInt viewHeight = iViewSize.iHeight; |
|
1654 TInt offsetHeight = curViewPosY - ( viewHeight / 2 ); |
|
1655 TInt deltaPixels = 0; |
|
1656 switch (aCursorMovement) |
|
1657 { |
|
1658 case CListBoxView::ECursorNextScreen: |
|
1659 { |
|
1660 if ( viewHeight > worldHeight - offsetHeight - viewHeight ) |
|
1661 { |
|
1662 if ( worldHeight - offsetHeight - viewHeight > 0 ) |
|
1663 { |
|
1664 iListBox.iView->MoveCursorL(CListBoxView::ECursorLastItem, aSelectionMode); |
|
1665 } |
|
1666 break; |
|
1667 } |
|
1668 deltaPixels = viewHeight; |
|
1669 break; |
|
1670 } |
|
1671 case CListBoxView::ECursorPrevScreen: |
|
1672 { |
|
1673 if ( viewHeight > offsetHeight ) |
|
1674 { |
|
1675 if ( offsetHeight > 0 ) |
|
1676 { |
|
1677 iListBox.iView->MoveCursorL(CListBoxView::ECursorFirstItem, aSelectionMode); |
|
1678 } |
|
1679 break; |
|
1680 } |
|
1681 deltaPixels = -viewHeight; |
|
1682 break; |
|
1683 } |
|
1684 default: |
|
1685 { |
|
1686 _AKNTRACE_FUNC_EXIT; |
|
1687 return EFalse; |
|
1688 } |
|
1689 } |
|
1690 |
|
1691 if ( deltaPixels != 0 ) |
|
1692 { |
|
1693 TPoint newPosition( iViewPosition.iX, |
|
1694 deltaPixels + curViewPosY ); |
|
1695 ViewPositionChanged( newPosition ); |
|
1696 } |
|
1697 _AKNTRACE_FUNC_EXIT; |
|
1698 return ETrue; |
|
1699 } |
|
1700 |
|
1701 // --------------------------------------------------------------------------- |
|
1702 // CListBoxExt::ImmediateFeedback |
|
1703 // --------------------------------------------------------------------------- |
|
1704 // |
|
1705 void CListBoxExt::ImmediateFeedback( TTouchLogicalFeedback aFeedback, |
|
1706 TTouchFeedbackType aFeedbackType, |
|
1707 const TPointerEvent& aPointerEvent ) |
|
1708 { |
|
1709 _AKNTRACE_FUNC_ENTER; |
|
1710 if ( iFeedback ) |
|
1711 { |
|
1712 iFeedback->InstantFeedback( &iListBox, aFeedback, aFeedbackType, aPointerEvent ); |
|
1713 } |
|
1714 _AKNTRACE_FUNC_EXIT; |
|
1715 } |
|
1716 |
|
1717 // --------------------------------------------------------------------------- |
|
1718 // CListBoxExt::FeedbackEnabledOnUpEvent |
|
1719 // --------------------------------------------------------------------------- |
|
1720 // |
|
1721 TBool CListBoxExt::FeedbackEnabledOnUpEvent() |
|
1722 { |
|
1723 _AKNTRACE_FUNC_ENTER; |
|
1724 TBool enabled( EFalse ); |
|
1725 if ( ( iListBox.iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) && |
|
1726 !iFlickStopped ) |
|
1727 { |
|
1728 enabled = ETrue; |
|
1729 } |
|
1730 _AKNTRACE_FUNC_EXIT; |
|
1731 return enabled; |
|
1732 } |
|
1733 |
|
1734 // --------------------------------------------------------------------------- |
|
1735 // CListBoxExt::SetFlickOngoing |
|
1736 // --------------------------------------------------------------------------- |
|
1737 // |
|
1738 void CListBoxExt::SetFlickOngoing( TBool aFlickOngoing ) |
|
1739 { |
|
1740 iFlickOngoing = aFlickOngoing; |
|
1741 } |
|
1742 |
|
1743 // --------------------------------------------------------------------------- |
|
1744 // CListBoxExt::SetPanningOngoing |
|
1745 // --------------------------------------------------------------------------- |
|
1746 // |
|
1747 void CListBoxExt::SetPanningOngoing( TBool aPanningOngoing ) |
|
1748 { |
|
1749 iPanningOngoing = aPanningOngoing; |
|
1750 } |
|
1751 |
|
1752 // --------------------------------------------------------------------------- |
|
1753 // CListBoxExt::FlickOrPanningOngoing |
|
1754 // --------------------------------------------------------------------------- |
|
1755 // |
|
1756 TBool CListBoxExt::FlickOrPanningOngoing() |
|
1757 { |
|
1758 return ( iFlickOngoing | iPanningOngoing ); |
|
1759 } |
|
1760 |
|
1761 // --------------------------------------------------------------------------- |
|
1762 // CListBoxExt::ListBottomLimit |
|
1763 // --------------------------------------------------------------------------- |
|
1764 // |
|
1765 TInt CListBoxExt::ListBottomLimit() |
|
1766 { |
|
1767 return iListBottomLimit; |
|
1768 } |
|
1769 |
|
1770 // |
|
1771 // class CEikListBox |
|
1772 // |
|
1773 |
|
1774 const TInt KEikListBoxHNudgeSizeAsFractionOfViewRectWidth = 20; |
|
1775 // const TInt KEikListBoxBackgroundColor = 15; later, this will be a data member of the listbox |
|
1776 const TInt KEikListBoxItemVGap = 6; // to allow a box to be drawn around each item |
|
1777 const TInt KEikListBoxInterItemGap = 2; |
|
1778 |
|
1779 GLDEF_C void Panic(TEikListBoxPanic aPanic) |
|
1780 { |
|
1781 _LIT(KPanicCat,"EIKON-LISTBOX"); |
|
1782 User::Panic(KPanicCat,aPanic); |
|
1783 } |
|
1784 |
|
1785 EXPORT_C CEikListBox::CEikListBox() |
|
1786 /*DFRD can setup 4 margins (top, bottom, left, right) by setting iHorizontalMargin |
|
1787 to KLafListboxUseLafHorizMargins and iVerticalMargin to KLafListboxUseLafVertMargins. |
|
1788 The DFRD can also use 3 margins by setting either of these 2 values (iHorizonatalMargin |
|
1789 or iVerticalMargin) to another integer. The application developer can only set 2 |
|
1790 margins; iHorizontalMargin and iVerticalMargin*/ |
|
1791 : iItemEditor(NULL) |
|
1792 { |
|
1793 _AKNTRACE_FUNC_ENTER; |
|
1794 LafListBox::GetDefaultBorder(iBorder); |
|
1795 iMargins = LafListBox::Margins(); |
|
1796 |
|
1797 iItemHeight = iEikonEnv->NormalFont()->HeightInPixels() + KEikListBoxItemVGap; |
|
1798 iBackColor = iEikonEnv->Color(EColorControlBackground); |
|
1799 |
|
1800 SetComponentsToInheritVisibility(EFalse); |
|
1801 AKNTASHOOK_ADD( this, "CEikListBox" ); |
|
1802 _AKNTRACE_FUNC_EXIT; |
|
1803 } |
|
1804 |
|
1805 EXPORT_C void CEikListBox::SetItemsInSingleLine( TInt aItems ) |
|
1806 { |
|
1807 if ( iListBoxExt ) |
|
1808 { |
|
1809 iListBoxExt->iItemsInSingleLine = aItems; |
|
1810 } |
|
1811 } |
|
1812 |
|
1813 EXPORT_C void CEikListBox::UpdateViewColors() |
|
1814 { |
|
1815 _AKNTRACE_FUNC_ENTER; |
|
1816 if(!iView) |
|
1817 { |
|
1818 _AKNTRACE_FUNC_EXIT; |
|
1819 return; |
|
1820 } |
|
1821 |
|
1822 if(IsDimmed()) |
|
1823 { |
|
1824 iView->SetTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this)); |
|
1825 iView->SetBackColor(iEikonEnv->ControlColor(EColorControlDimmedBackground,*this)); |
|
1826 iView->SetMatcherCursorColor(iEikonEnv->ControlColor(EColorControlHighlightBackground,*this)); |
|
1827 } |
|
1828 else |
|
1829 { |
|
1830 iView->SetTextColor(iEikonEnv->ControlColor(EColorControlText,*this)); |
|
1831 iView->SetBackColor(iEikonEnv->ControlColor(EColorControlBackground,*this)); |
|
1832 iView->SetMatcherCursorColor(iEikonEnv->ControlColor(EColorControlDimmedHighlightBackground,*this)); |
|
1833 } |
|
1834 _AKNTRACE_FUNC_EXIT; |
|
1835 } |
|
1836 |
|
1837 EXPORT_C void CEikListBox::UpdateItemDrawerColors() |
|
1838 { |
|
1839 _AKNTRACE_FUNC_ENTER; |
|
1840 if(!iItemDrawer) |
|
1841 { |
|
1842 _AKNTRACE_FUNC_EXIT; |
|
1843 return; |
|
1844 } |
|
1845 |
|
1846 if(IsDimmed()) |
|
1847 { |
|
1848 iItemDrawer->SetTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this)); |
|
1849 iItemDrawer->SetHighlightedTextColor(iEikonEnv->ControlColor(EColorControlDimmedHighlightText,*this)); |
|
1850 iItemDrawer->SetDimmedTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this)); |
|
1851 iItemDrawer->SetBackColor(iEikonEnv->ControlColor(EColorControlDimmedBackground,*this)); |
|
1852 iItemDrawer->SetHighlightedBackColor(iEikonEnv->ControlColor(EColorControlDimmedHighlightBackground,*this)); |
|
1853 iItemDrawer->SetDimmedBackColor(iEikonEnv->ControlColor(EColorControlDimmedBackground,*this)); |
|
1854 } |
|
1855 else |
|
1856 { |
|
1857 iItemDrawer->SetTextColor(iEikonEnv->ControlColor(EColorControlText,*this)); |
|
1858 iItemDrawer->SetHighlightedTextColor(iEikonEnv->ControlColor(EColorControlHighlightText,*this)); |
|
1859 iItemDrawer->SetDimmedTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this)); |
|
1860 iItemDrawer->SetBackColor(iEikonEnv->ControlColor(EColorControlBackground,*this)); |
|
1861 iItemDrawer->SetHighlightedBackColor(iEikonEnv->ControlColor(EColorControlHighlightBackground,*this)); |
|
1862 iItemDrawer->SetDimmedBackColor(iEikonEnv->ControlColor(EColorControlBackground,*this)); |
|
1863 } |
|
1864 _AKNTRACE_FUNC_EXIT; |
|
1865 } |
|
1866 |
|
1867 EXPORT_C void CEikListBox::FireItemChange() |
|
1868 { |
|
1869 if( iListBoxExt ) |
|
1870 { |
|
1871 iListBoxExt->FireItemChange( this ); |
|
1872 } |
|
1873 } |
|
1874 |
|
1875 EXPORT_C CEikListBox::~CEikListBox() |
|
1876 { |
|
1877 _AKNTRACE_FUNC_ENTER; |
|
1878 AKNTASHOOK_REMOVE(); |
|
1879 if (iCoeEnv && iEikonEnv && iAvkonEnv) |
|
1880 iAvkonEnv->RemoveCbaObserver(); |
|
1881 |
|
1882 if (iListBoxExt) |
|
1883 { |
|
1884 iListBoxExt->RemoveMSKObserver(this); |
|
1885 delete iListBoxExt; |
|
1886 iListBoxExt = NULL; |
|
1887 } |
|
1888 |
|
1889 delete iSBFrame; |
|
1890 |
|
1891 if (!(iListBoxFlags & EKeepModel)) |
|
1892 delete iModel; |
|
1893 |
|
1894 if (iView) |
|
1895 delete iView; |
|
1896 else |
|
1897 delete iItemDrawer; |
|
1898 |
|
1899 if (iLaunchingButton) |
|
1900 { |
|
1901 TPointerEvent event; |
|
1902 event.iType=TPointerEvent::EButton1Up; |
|
1903 event.iModifiers=0; |
|
1904 event.iPosition=iLaunchingButton->Position(); |
|
1905 TRAP_IGNORE(iLaunchingButton->HandlePointerEventL(event)); |
|
1906 } |
|
1907 |
|
1908 ResetItemEditor(); |
|
1909 _AKNTRACE_FUNC_EXIT; |
|
1910 } |
|
1911 |
|
1912 void CEikListBox::InformMSKButtonGroupDeletion() |
|
1913 { |
|
1914 if (iListBoxExt) |
|
1915 { |
|
1916 iListBoxExt->iMSKButtonGroupAlive = EFalse; |
|
1917 } |
|
1918 } |
|
1919 |
|
1920 EXPORT_C TBool CEikListBox::ItemExists(TInt aItemIndex) const |
|
1921 { |
|
1922 return ((aItemIndex >= 0) && (aItemIndex < iModel->NumberOfItems())); |
|
1923 } |
|
1924 |
|
1925 EXPORT_C void CEikListBox::RestoreCommonListBoxPropertiesL(TResourceReader& aReader) |
|
1926 { |
|
1927 _AKNTRACE_FUNC_ENTER; |
|
1928 aReader.ReadInt8(); // version |
|
1929 iListBoxFlags = aReader.ReadInt32(); |
|
1930 |
|
1931 iRequiredHeightInNumOfItems = aReader.ReadInt16(); |
|
1932 |
|
1933 if (! (iListBoxFlags & EPageAtOnceScrolling)) |
|
1934 { // no loop scroll for viewers |
|
1935 iListBoxFlags |= ELoopScrolling; // All lists will have loop scrolling. |
|
1936 } |
|
1937 |
|
1938 if (iListBoxFlags & EIncrementalMatching) |
|
1939 CreateMatchBufferL(); |
|
1940 _AKNTRACE_FUNC_EXIT; |
|
1941 } |
|
1942 |
|
1943 EXPORT_C MListBoxModel* CEikListBox::Model() const |
|
1944 { |
|
1945 return iModel; |
|
1946 } |
|
1947 |
|
1948 EXPORT_C CListBoxView* CEikListBox::View() const |
|
1949 { |
|
1950 return iView; |
|
1951 } |
|
1952 |
|
1953 EXPORT_C void CEikListBox::CreateMatchBufferL() |
|
1954 { |
|
1955 CheckCreateExtensionL(); |
|
1956 iListBoxExt->CreateMatchBufferL(); |
|
1957 } |
|
1958 |
|
1959 EXPORT_C void CEikListBox::SetItemHeightL(TInt aHeight) |
|
1960 { |
|
1961 _AKNTRACE_FUNC_ENTER; |
|
1962 _AKNTRACE( "aHeight = %d", aHeight ); |
|
1963 // won't actually leave if the horizontal/vertical scrollbars have both been turned off |
|
1964 __ASSERT_ALWAYS((aHeight > 0), Panic(EEikPanicListBoxInvalidItemHeightSpecified)); |
|
1965 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1966 TRect lastViewRect( iView->ViewRect() ); |
|
1967 #endif |
|
1968 iItemHeight = aHeight; |
|
1969 TRect clientRect = iBorder.InnerRect(Rect()); |
|
1970 iView->SetItemHeight(aHeight); |
|
1971 SetViewRectFromClientRect(clientRect); |
|
1972 HandleViewRectSizeChangeL(); |
|
1973 |
|
1974 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1975 if( iView->ViewRect() != lastViewRect ) |
|
1976 { |
|
1977 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
1978 if ( transApi ) |
|
1979 { |
|
1980 transApi->Remove( MAknListBoxTfxInternal:: EListEverything ); |
|
1981 } |
|
1982 } |
|
1983 #endif |
|
1984 _AKNTRACE_FUNC_EXIT; |
|
1985 } |
|
1986 |
|
1987 EXPORT_C TInt CEikListBox::ItemHeight() const |
|
1988 { |
|
1989 return iItemHeight; |
|
1990 } |
|
1991 |
|
1992 EXPORT_C TInt CEikListBox::CalcWidthBasedOnNumOfChars(TInt aNumOfChars) const |
|
1993 { |
|
1994 return CalcWidthBasedOnRequiredItemWidth(aNumOfChars * iEikonEnv->NormalFont()->MaxNormalCharWidthInPixels()); |
|
1995 } |
|
1996 |
|
1997 EXPORT_C TInt CEikListBox::CalcWidthBasedOnRequiredItemWidth(TInt aTextWidthInPixels) const |
|
1998 { |
|
1999 _AKNTRACE_FUNC_ENTER; |
|
2000 _AKNTRACE("aTextWidthInPixels = %d", aTextWidthInPixels); |
|
2001 TInt width = aTextWidthInPixels; |
|
2002 if (iItemDrawer->Flags()&CListItemDrawer::EDrawMarkSelection) |
|
2003 { |
|
2004 width += iItemDrawer->MarkColumn() + iItemDrawer->MarkGutter(); |
|
2005 } |
|
2006 width += (LafListBox::InnerGutter() + ListBoxMargins().iLeft + ListBoxMargins().iRight); |
|
2007 width += iBorder.SizeDelta().iWidth; |
|
2008 if (iSBFrame) |
|
2009 { |
|
2010 #if COMMENTED_FOR_SERIES60_BECAUSE_SCROLLBAR_BREADTH_IS_NONZERO |
|
2011 if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff) |
|
2012 width += CEikScrollBar::DefaultScrollBarBreadth(); |
|
2013 #endif |
|
2014 } |
|
2015 _AKNTRACE( "width = %d", width ); |
|
2016 _AKNTRACE_FUNC_EXIT; |
|
2017 return width; |
|
2018 } |
|
2019 |
|
2020 EXPORT_C TInt CEikListBox::CalcHeightBasedOnNumOfItems(TInt aNumOfItems) const |
|
2021 { |
|
2022 _AKNTRACE_FUNC_ENTER; |
|
2023 _AKNTRACE( "aNumOfItems = %d", aNumOfItems ); |
|
2024 TInt height; |
|
2025 height = (aNumOfItems * iItemHeight); |
|
2026 height += (ListBoxMargins().iTop + ListBoxMargins().iBottom); |
|
2027 height += iBorder.SizeDelta().iHeight; |
|
2028 if (iSBFrame) |
|
2029 { |
|
2030 if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff) |
|
2031 height += CEikScrollBar::DefaultScrollBarBreadth(); |
|
2032 } |
|
2033 _AKNTRACE( "height = %d", height ); |
|
2034 _AKNTRACE_FUNC_EXIT; |
|
2035 return height; |
|
2036 } |
|
2037 |
|
2038 EXPORT_C TSize CEikListBox::MinimumSize() |
|
2039 { |
|
2040 _AKNTRACE_FUNC_ENTER; |
|
2041 TSize size; |
|
2042 TSize minCellSize(iItemDrawer->MinimumCellSize()); |
|
2043 size.iWidth = minCellSize.iWidth + ListBoxMargins().iLeft + ListBoxMargins().iRight; |
|
2044 size.iHeight = (ListBoxMargins().iTop + ListBoxMargins().iBottom) + (iRequiredHeightInNumOfItems * minCellSize.iHeight); |
|
2045 if ((!(iListBoxFlags & EScrollBarSizeExcluded)) && iSBFrame) |
|
2046 { |
|
2047 if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff) |
|
2048 size.iWidth += CEikScrollBar::DefaultScrollBarBreadth(); |
|
2049 if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff) |
|
2050 size.iHeight += CEikScrollBar::DefaultScrollBarBreadth(); |
|
2051 } |
|
2052 size += iBorder.SizeDelta(); |
|
2053 _AKNTRACE( "width = %d, height = %d", size.iWidth, size.iHeight ); |
|
2054 _AKNTRACE_FUNC_EXIT; |
|
2055 return size; |
|
2056 } |
|
2057 |
|
2058 EXPORT_C TSize CEikListBox::CalcSizeInPixels(TInt aWidthAsNumOfChars, TInt aHeightAsNumOfItems) const |
|
2059 { |
|
2060 return TSize(CalcWidthBasedOnNumOfChars(aWidthAsNumOfChars), CalcHeightBasedOnNumOfItems(aHeightAsNumOfItems)); |
|
2061 } |
|
2062 |
|
2063 EXPORT_C CEikScrollBarFrame* CEikListBox::CreateScrollBarFrameL(TBool aPreAlloc) |
|
2064 { |
|
2065 return CreateScrollBarFrameL(aPreAlloc, EFalse); |
|
2066 } |
|
2067 |
|
2068 EXPORT_C void CEikListBox::HandleViewRectSizeChangeL() |
|
2069 { |
|
2070 _AKNTRACE_FUNC_ENTER; |
|
2071 iView->CalcBottomItemIndex(); |
|
2072 iView->CalcDataWidth(); |
|
2073 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
2074 |
|
2075 if ( ItemExists(currentItemIndex) ) |
|
2076 { |
|
2077 TInt topItemIndex( iView->TopItemIndex() ); |
|
2078 TInt numberOfItems = iView->NumberOfItemsThatFitInRect( iView->ViewRect() ); |
|
2079 TInt newTopItemIndex( KEikListBoxInvalidIndex ); |
|
2080 |
|
2081 // Current item not visible or current item is the last item (not fully visible) |
|
2082 if ( !iView->ItemIsVisible(currentItemIndex) |
|
2083 || iListBoxExt && iListBoxExt->iPhysics |
|
2084 && currentItemIndex == ( topItemIndex + numberOfItems - 1 ) ) |
|
2085 { |
|
2086 newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( currentItemIndex ); |
|
2087 } |
|
2088 else |
|
2089 { |
|
2090 // recalculates top index of list when mode be changed |
|
2091 TInt totalItems = iModel->NumberOfItems(); |
|
2092 if ( (totalItems - topItemIndex) < numberOfItems ) |
|
2093 { |
|
2094 newTopItemIndex = Max( 0, totalItems - numberOfItems ); |
|
2095 } |
|
2096 } |
|
2097 |
|
2098 if ( newTopItemIndex != KEikListBoxInvalidIndex ) |
|
2099 { |
|
2100 iView->SetTopItemIndex( newTopItemIndex ); |
|
2101 if ( iListBoxExt && iListBoxExt->iPhysics ) |
|
2102 { |
|
2103 iListBoxExt->InitPhysicsL(); |
|
2104 } |
|
2105 } |
|
2106 } |
|
2107 UpdateScrollBarsL(); |
|
2108 _AKNTRACE_FUNC_EXIT; |
|
2109 } |
|
2110 |
|
2111 EXPORT_C void CEikListBox::SizeChanged() |
|
2112 { |
|
2113 _AKNTRACE_FUNC_ENTER; |
|
2114 TRect clientRect = iBorder.InnerRect(Rect()); |
|
2115 SetViewRectFromClientRect(clientRect); |
|
2116 TRAP_IGNORE(HandleViewRectSizeChangeL()); |
|
2117 _AKNTRACE_FUNC_EXIT; |
|
2118 } |
|
2119 |
|
2120 EXPORT_C TInt CEikListBox::CountComponentControls() const |
|
2121 { |
|
2122 TInt count=CEikBorderedControl::CountComponentControls(); |
|
2123 if (iSBFrame && (iSBFrameOwned == ENotOwnedExternally)) |
|
2124 { |
|
2125 if(iSBFrame->VerticalScrollBar()) |
|
2126 { |
|
2127 count+=iSBFrame->CountComponentControls(); |
|
2128 } |
|
2129 } |
|
2130 return count; |
|
2131 } |
|
2132 |
|
2133 EXPORT_C CCoeControl* CEikListBox::ComponentControl(TInt aIndex) const |
|
2134 { |
|
2135 TInt baseCount=CEikBorderedControl::CountComponentControls(); |
|
2136 if (aIndex<baseCount) |
|
2137 { |
|
2138 return CEikBorderedControl::ComponentControl(aIndex); |
|
2139 } |
|
2140 aIndex-=baseCount; |
|
2141 if( iSBFrame && iSBFrame->VerticalScrollBar() ) |
|
2142 { |
|
2143 return iSBFrame->ComponentControl(aIndex); |
|
2144 } |
|
2145 else |
|
2146 { |
|
2147 return NULL; |
|
2148 } |
|
2149 } |
|
2150 |
|
2151 EXPORT_C void CEikListBox::SetViewRectFromClientRect(const TRect& aClientRect) |
|
2152 { |
|
2153 _AKNTRACE_FUNC_ENTER; |
|
2154 TRect rect(aClientRect); |
|
2155 rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop, |
|
2156 rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom); |
|
2157 |
|
2158 if ( iListBoxExt && iListBoxExt->iPhysics ) |
|
2159 { |
|
2160 iViewRectHeightAdjustment = 0; |
|
2161 iView->SetViewRect(rect); |
|
2162 } |
|
2163 else |
|
2164 { |
|
2165 iItemHeight = iView->ItemSize().iHeight; |
|
2166 iViewRectHeightAdjustment = AdjustRectHeightToWholeNumberOfItems(rect); |
|
2167 iView->SetViewRect(rect); |
|
2168 } |
|
2169 |
|
2170 if ( iListBoxExt && |
|
2171 (iListBoxExt->iViewSize != rect.Size() )) |
|
2172 { |
|
2173 iListBoxExt->iViewSize = rect.Size(); |
|
2174 } |
|
2175 _AKNTRACE_FUNC_EXIT; |
|
2176 } |
|
2177 |
|
2178 EXPORT_C void CEikListBox::RestoreClientRectFromViewRect(TRect& aClientRect) const |
|
2179 { |
|
2180 _AKNTRACE_FUNC_ENTER; |
|
2181 aClientRect=iView->ViewRect(); |
|
2182 aClientRect.SetRect(aClientRect.iTl.iX - ListBoxMargins().iLeft, aClientRect.iTl.iY - ListBoxMargins().iTop, |
|
2183 aClientRect.iBr.iX + ListBoxMargins().iRight, aClientRect.iBr.iY + ListBoxMargins().iBottom); |
|
2184 // height may have been rounded so correct it |
|
2185 if (!iViewRectHeightAdjustment) |
|
2186 return; |
|
2187 #ifdef ORIGINAL_UIKON_CODE |
|
2188 if (iViewRectHeightAdjustment % 2 !=0) |
|
2189 aClientRect.iBr.iY += 1; |
|
2190 aClientRect.Grow(0, iViewRectHeightAdjustment/2); |
|
2191 #else // Series60 code |
|
2192 aClientRect.iBr.iY += iViewRectHeightAdjustment; |
|
2193 #endif |
|
2194 _AKNTRACE_FUNC_EXIT; |
|
2195 // aClientRect.iBr.iY += iViewRectHeightAdjustment; |
|
2196 } |
|
2197 |
|
2198 EXPORT_C TInt CEikListBox::AdjustRectHeightToWholeNumberOfItems(TRect& aRect) const |
|
2199 { |
|
2200 _AKNTRACE_FUNC_ENTER; |
|
2201 // round down the height of aRect (if necessary) so that only a whole number of items can be displayed inside the listbox |
|
2202 // returns the number of pixels reduced. |
|
2203 #ifdef ORIGINAL_UIKON_CODE |
|
2204 TInt remainder = aRect.Height() % iItemHeight; |
|
2205 if (remainder != 0) |
|
2206 { |
|
2207 // need to adjust viewRect |
|
2208 aRect.Shrink(0, remainder/2); |
|
2209 if (remainder % 2 != 0) |
|
2210 aRect.iBr.iY -= 1; |
|
2211 // aRect.iBr.iY -= remainder; |
|
2212 } |
|
2213 #else // Series 60 code |
|
2214 // To catch places which use this in series 60 |
|
2215 // -- should use derived class version |
|
2216 // from CAknColumnList or CEikFormattedCellListBox or something else. |
|
2217 //__ASSERT_DEBUG(0, Panic(0)); |
|
2218 // This is dead code, can be reverted to original once we've tested |
|
2219 // noone uses this. |
|
2220 TInt remainder = aRect.Height() % iItemHeight; |
|
2221 if (remainder != 0) |
|
2222 { |
|
2223 aRect.iBr.iY -= remainder; |
|
2224 } |
|
2225 #endif |
|
2226 _AKNTRACE_FUNC_EXIT; |
|
2227 return remainder; |
|
2228 } |
|
2229 |
|
2230 EXPORT_C void CEikListBox::CalculatePopoutRect(TInt aTargetItemIndex, TInt aTargetYPos, TRect& aListBoxRect, TInt aMinHeightInNumOfItems) |
|
2231 { |
|
2232 _AKNTRACE_FUNC_ENTER; |
|
2233 /*controlling the maximum width, in pixels, of a choice list*/ |
|
2234 if((LafListBox::MaxCellWidthInNumOfPixels() != KLafListBoxNoMaxCellWidth) && (aListBoxRect.Width() > LafListBox::MaxCellWidthInNumOfPixels())) |
|
2235 { |
|
2236 aListBoxRect.iBr.iX = aListBoxRect.iTl.iX + LafListBox::MaxCellWidthInNumOfPixels(); |
|
2237 } |
|
2238 // this function is designed for use by the choice list control |
|
2239 TInt listBoxHeight = 0; |
|
2240 TInt listBoxYPos = 0; |
|
2241 TInt screenHeight = iAvkonAppUi->ApplicationRect().Height(); /*iCoeEnv->ScreenDevice()->SizeInPixels().iHeight;*/ |
|
2242 TInt maxDisplayedItems = (screenHeight - (ListBoxMargins().iTop + ListBoxMargins().iBottom) - iBorder.SizeDelta().iHeight) / iItemHeight; |
|
2243 |
|
2244 /*controlling the maximum number of items displayed in a choice list*/ |
|
2245 if(LafListBox::MaxHeightInNumOfItems() != KLafListBoxNoMaxHeightInNumOfItems) |
|
2246 { |
|
2247 maxDisplayedItems = Min(maxDisplayedItems,LafListBox::MaxHeightInNumOfItems()); |
|
2248 } |
|
2249 TInt desiredHeightInNumOfItems = Max(iModel->NumberOfItems(), aMinHeightInNumOfItems); |
|
2250 if (desiredHeightInNumOfItems > maxDisplayedItems) |
|
2251 { |
|
2252 listBoxHeight = CalcHeightBasedOnNumOfItems(maxDisplayedItems); |
|
2253 listBoxYPos = (screenHeight - listBoxHeight) / 2; |
|
2254 TInt numOfDisplayedItemsAboveTarget = (aTargetYPos-listBoxYPos-ListBoxMargins().iTop)/iItemHeight; |
|
2255 |
|
2256 TInt topItemOrdinal=Max(0, (aTargetItemIndex-numOfDisplayedItemsAboveTarget)); |
|
2257 topItemOrdinal=Min(iModel->NumberOfItems()-maxDisplayedItems,topItemOrdinal); |
|
2258 iView->SetTopItemIndex(iView->TopItemIndex()+topItemOrdinal); |
|
2259 aListBoxRect.iTl.iY = listBoxYPos; |
|
2260 aListBoxRect.iBr.iY = listBoxYPos + listBoxHeight; |
|
2261 return; |
|
2262 } |
|
2263 listBoxHeight = CalcHeightBasedOnNumOfItems(desiredHeightInNumOfItems); |
|
2264 TInt numOfItemsAbove = aTargetItemIndex; |
|
2265 TInt potentialPixelsAboveTarget = 0; |
|
2266 if (numOfItemsAbove > 0) |
|
2267 { |
|
2268 potentialPixelsAboveTarget = numOfItemsAbove * iItemHeight + ListBoxMargins().iTop + iBorder.Margins().iTop; |
|
2269 } |
|
2270 listBoxYPos = aTargetYPos - potentialPixelsAboveTarget; |
|
2271 if ((listBoxYPos + listBoxHeight) >= screenHeight) |
|
2272 listBoxYPos = screenHeight - listBoxHeight; |
|
2273 if (potentialPixelsAboveTarget>aTargetYPos) |
|
2274 listBoxYPos = 0; |
|
2275 // find number of items below aTargetItemIndex |
|
2276 TInt numberOfItemsBelowTarget = 0; |
|
2277 TInt targetIndex = aTargetItemIndex; |
|
2278 while (ItemExists(++targetIndex)) |
|
2279 ++numberOfItemsBelowTarget; |
|
2280 TInt potentialPixelsBelowTarget = 0; |
|
2281 if (numberOfItemsBelowTarget > 0) |
|
2282 { |
|
2283 potentialPixelsBelowTarget = numberOfItemsBelowTarget * iItemHeight + ListBoxMargins().iBottom + iBorder.Margins().iBottom; |
|
2284 } |
|
2285 if ((potentialPixelsBelowTarget + iItemHeight) > (screenHeight-aTargetYPos)) |
|
2286 listBoxYPos = screenHeight - listBoxHeight; |
|
2287 aListBoxRect.iTl.iY = listBoxYPos; |
|
2288 aListBoxRect.iBr.iY = listBoxYPos + listBoxHeight; |
|
2289 _AKNTRACE_FUNC_EXIT; |
|
2290 } |
|
2291 |
|
2292 EXPORT_C TInt CEikListBox::TopItemIndex() const |
|
2293 { |
|
2294 _AKNTRACE( "iTopItemIndex = %d", iView->TopItemIndex() ); |
|
2295 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
2296 return iView->TopItemIndex(); |
|
2297 } |
|
2298 |
|
2299 EXPORT_C TInt CEikListBox::BottomItemIndex() const |
|
2300 { |
|
2301 _AKNTRACE( "iBottomItemIndex = %d", iView->BottomItemIndex() ); |
|
2302 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
2303 return iView->BottomItemIndex(); |
|
2304 } |
|
2305 |
|
2306 EXPORT_C void CEikListBox::SetTopItemIndex(TInt aItemIndex) const |
|
2307 { |
|
2308 _AKNTRACE( "aItemIndex = %d", aItemIndex ); |
|
2309 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
2310 iView->SetTopItemIndex(aItemIndex); |
|
2311 UpdateScrollBarThumbs(); |
|
2312 } |
|
2313 |
|
2314 EXPORT_C void CEikListBox::AdjustTopItemIndex() const |
|
2315 { |
|
2316 _AKNTRACE_FUNC_ENTER; |
|
2317 TInt maxTopItemIndex=iView->BottomItemIndex() - iView->NumberOfItemsThatFitInRect(iView->ViewRect()) +1; |
|
2318 maxTopItemIndex=Max(0, maxTopItemIndex); |
|
2319 if (iView->TopItemIndex() > maxTopItemIndex) |
|
2320 SetTopItemIndex(maxTopItemIndex); |
|
2321 _AKNTRACE_FUNC_EXIT; |
|
2322 } |
|
2323 |
|
2324 EXPORT_C TInt CEikListBox::CurrentItemIndex() const |
|
2325 { |
|
2326 _AKNTRACE( "iView->CurrentItemIndex() is %d", iView->CurrentItemIndex() ); |
|
2327 __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView)); |
|
2328 return iView->CurrentItemIndex(); |
|
2329 } |
|
2330 |
|
2331 EXPORT_C void CEikListBox::UpdateCurrentItem(TInt aItemIndex) const |
|
2332 { |
|
2333 _AKNTRACE_FUNC_ENTER; |
|
2334 TInt oldCurrentItemIndex = iView->CurrentItemIndex(); |
|
2335 iView->SetCurrentItemIndex(aItemIndex); |
|
2336 if ( IsReadyToDraw() ) |
|
2337 { |
|
2338 iView->DrawItem(oldCurrentItemIndex); |
|
2339 } |
|
2340 if (!(iView->ItemIsVisible(aItemIndex)) || iView->ItemIsPartiallyVisible(aItemIndex) ) |
|
2341 { |
|
2342 SetTopItemIndex(iView->CalcNewTopItemIndexSoItemIsVisible(aItemIndex)); |
|
2343 |
|
2344 if ( !iView->RedrawDisabled() ) |
|
2345 { |
|
2346 DrawNow(); |
|
2347 } |
|
2348 } |
|
2349 #if NOT_USED_IN_SERIES60 |
|
2350 // This is not used in Series 60 because in FIND, we do not want |
|
2351 // selectionindexes to have a list of indexes... |
|
2352 if (!(iListBoxFlags & EMultipleSelection)) |
|
2353 { |
|
2354 TRAPD(err,iView->UpdateSelectionL(CListBoxView::ESingleSelection)); |
|
2355 if (err!=KErrNone) |
|
2356 iEikonEnv->NotifyIdleErrorWhileRedrawing(err); |
|
2357 } |
|
2358 #endif |
|
2359 |
|
2360 iView->DrawItem(aItemIndex); |
|
2361 TRAP_IGNORE(UpdateMarkUnmarkMSKL()); |
|
2362 UpdateScrollBarThumbs(); |
|
2363 _AKNTRACE_FUNC_EXIT; |
|
2364 } |
|
2365 |
|
2366 EXPORT_C void CEikListBox::SetCurrentItemIndex(TInt aItemIndex) const |
|
2367 { |
|
2368 _AKNTRACE_FUNC_ENTER; |
|
2369 _AKNTRACE( "aItemIndex = %d", aItemIndex ); |
|
2370 __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView)); |
|
2371 TBool redrawDisabled = iView->RedrawDisabled(); |
|
2372 iView->SetDisableRedraw(ETrue); |
|
2373 UpdateCurrentItem(aItemIndex); |
|
2374 iView->SetDisableRedraw(redrawDisabled); |
|
2375 |
|
2376 if ( iListBoxExt && iListBoxExt->iPhysics && aItemIndex == 0 ) |
|
2377 { |
|
2378 iView->SetItemOffsetInPixels( 0 ); |
|
2379 } |
|
2380 _AKNTRACE_FUNC_EXIT; |
|
2381 } |
|
2382 |
|
2383 EXPORT_C void CEikListBox::SetCurrentItemIndexAndDraw(TInt aItemIndex) const |
|
2384 { |
|
2385 __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView)); |
|
2386 UpdateCurrentItem(aItemIndex); |
|
2387 } |
|
2388 |
|
2389 EXPORT_C void CEikListBox::ConstructL(const CCoeControl* aParent,TInt aFlags) |
|
2390 { |
|
2391 _AKNTRACE_FUNC_ENTER; |
|
2392 iListBoxFlags = aFlags; |
|
2393 if (! (iListBoxFlags & EPageAtOnceScrolling)) |
|
2394 { // no loop scroll for viewers |
|
2395 iListBoxFlags |= ELoopScrolling; // All lists will have loop scrolling. |
|
2396 } |
|
2397 if (aParent) |
|
2398 SetContainerWindowL(*aParent); |
|
2399 else |
|
2400 { |
|
2401 CreateWindowL(aParent); |
|
2402 |
|
2403 if ( CAknEnv::Static()->TransparencyEnabled() ) |
|
2404 { |
|
2405 Window().SetRequiredDisplayMode( EColor16MA ); |
|
2406 TInt err = Window().SetTransparencyAlphaChannel(); |
|
2407 |
|
2408 if ( err == KErrNone ) |
|
2409 { |
|
2410 Window().SetBackgroundColor(~0); |
|
2411 } |
|
2412 } |
|
2413 |
|
2414 EnableDragEvents(); |
|
2415 Window().SetPointerGrab(ETrue); |
|
2416 } |
|
2417 if (iListBoxFlags & EPopout) |
|
2418 { |
|
2419 if (!LafListBox::FadeBehind()) |
|
2420 DrawableWindow()->EnableBackup(); |
|
2421 LafListBox::GetDefaultPopoutBorder(iBorder); |
|
2422 } |
|
2423 if (iListBoxFlags & EIncrementalMatching) |
|
2424 CreateMatchBufferL(); |
|
2425 CreateViewL(); |
|
2426 |
|
2427 if(iItemDrawer && (iItemDrawer->MinimumCellSize().iHeight != 0)) |
|
2428 iItemHeight = iItemDrawer->MinimumCellSize().iHeight; |
|
2429 |
|
2430 CheckCreateExtensionL(); |
|
2431 |
|
2432 if ( iListBoxExt->iLongTapDetector |
|
2433 && iListBoxFlags & EDisableItemSpecificMenu ) |
|
2434 { |
|
2435 delete iListBoxExt->iLongTapDetector; |
|
2436 iListBoxExt->iLongTapDetector = NULL; |
|
2437 } |
|
2438 _AKNTRACE_FUNC_EXIT; |
|
2439 } |
|
2440 |
|
2441 EXPORT_C void CEikListBox::ConstructL(MListBoxModel* aListBoxModel,CListItemDrawer* aListItemDrawer,const CCoeControl* aParent,TInt aFlags) |
|
2442 { |
|
2443 _AKNTRACE_FUNC_ENTER; |
|
2444 __ASSERT_DEBUG(aListBoxModel!=NULL,Panic(EEikPanicListBoxInvalidModelSpecified)); |
|
2445 __ASSERT_DEBUG(aListItemDrawer!=NULL,Panic(EEikPanicListBoxInvalidItemDrawerSpecified)); |
|
2446 iModel = aListBoxModel; |
|
2447 iItemDrawer = aListItemDrawer; |
|
2448 ConstructL(aParent,aFlags); |
|
2449 _AKNTRACE_FUNC_EXIT; |
|
2450 } |
|
2451 |
|
2452 EXPORT_C void CEikListBox::ConstructL(MListBoxModel* aListBoxModel, CListItemDrawer* aListItemDrawer, const CCoeControl* aParent, TGulBorder aBorder, TInt aFlags) |
|
2453 { |
|
2454 _AKNTRACE_FUNC_ENTER; |
|
2455 iBorder = aBorder; |
|
2456 CEikListBox::ConstructL(aListBoxModel, aListItemDrawer, aParent, aFlags); |
|
2457 _AKNTRACE_FUNC_EXIT; |
|
2458 } |
|
2459 |
|
2460 EXPORT_C void CEikListBox::SetListBoxObserver(MEikListBoxObserver* aObserver) |
|
2461 { |
|
2462 iListBoxObserver = aObserver; |
|
2463 } |
|
2464 |
|
2465 EXPORT_C void CEikListBox::SetContainerWindowL(const CCoeControl& aParent) |
|
2466 { |
|
2467 _AKNTRACE_FUNC_ENTER; |
|
2468 if ((iListBoxFlags & ECreateOwnWindow) || (iListBoxFlags & EPopout)) |
|
2469 { |
|
2470 CreateWindowL(&aParent); |
|
2471 if (iListBoxFlags & EPopout) |
|
2472 DrawableWindow()->EnableBackup(); |
|
2473 } |
|
2474 else |
|
2475 CCoeControl::SetContainerWindowL(aParent); |
|
2476 EnableDragEvents(); |
|
2477 Window().SetPointerGrab(ETrue); |
|
2478 |
|
2479 if ( iListBoxExt && iListBoxExt->iPhysics ) |
|
2480 { |
|
2481 iListBoxExt->iPhysics->UpdateViewWindowControl(); |
|
2482 } |
|
2483 _AKNTRACE_FUNC_EXIT; |
|
2484 } |
|
2485 |
|
2486 EXPORT_C CListBoxView* CEikListBox::MakeViewClassInstanceL() |
|
2487 { |
|
2488 return (new(ELeave) CListBoxView); |
|
2489 } |
|
2490 |
|
2491 EXPORT_C void CEikListBox::CreateViewL() |
|
2492 { |
|
2493 _AKNTRACE_FUNC_ENTER; |
|
2494 // assert that the model and item drawer aren't null |
|
2495 if (iView) |
|
2496 { |
|
2497 _AKNTRACE_FUNC_EXIT; |
|
2498 return; |
|
2499 } |
|
2500 iView = MakeViewClassInstanceL(); |
|
2501 iView->ConstructL(iModel, iItemDrawer, iEikonEnv->ScreenDevice(), &(iEikonEnv->RootWin()), &Window(), Rect(), iItemHeight); |
|
2502 iView->iExtension->iListBox = this; |
|
2503 |
|
2504 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2505 // LISTBOX EFFECTS IMPLEMENTATION |
|
2506 // |
|
2507 // Creates a CTfxGc and replaces the original CWindowGc with that gc. |
|
2508 // |
|
2509 CWindowGc* transGc = CAknListLoader::CreateTfxGc( *this ); |
|
2510 if( transGc ) |
|
2511 { |
|
2512 iView->iGc = transGc; |
|
2513 iView->ItemDrawer()->SetGc(transGc); |
|
2514 } |
|
2515 // END OF LISTBOX EFFECTS IMPLEMENTATION |
|
2516 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2517 |
|
2518 if (iListBoxFlags & EIncrementalMatching) |
|
2519 { |
|
2520 iView->SetMatcherCursor(ETrue); |
|
2521 if(IsDimmed()) |
|
2522 iView->SetMatcherCursorColor(EColorControlHighlightBackground); |
|
2523 else |
|
2524 iView->SetMatcherCursorColor(EColorControlDimmedHighlightBackground); |
|
2525 } |
|
2526 iItemDrawer->SetVerticalInterItemGap(KEikListBoxItemVGap); |
|
2527 if (iListBoxFlags & EMultipleSelection) iItemDrawer->SetDrawMark(ETrue); |
|
2528 if (ItemExists(0)) |
|
2529 SetCurrentItemIndex(0); |
|
2530 CheckCreateExtensionL(); |
|
2531 |
|
2532 if ( iListBoxExt && iListBoxExt->iPhysics ) |
|
2533 { |
|
2534 iView->iExtension->iScrollingDisabled = EFalse; |
|
2535 } |
|
2536 |
|
2537 iView->SetVisibilityObserver(iListBoxExt); |
|
2538 if ( iListBoxFlags & EPaintedSelection ) |
|
2539 { |
|
2540 iView->SetPaintedSelection( ETrue ); |
|
2541 iItemDrawer->SetDrawMark( EFalse ); |
|
2542 iItemDrawer->SetFlags( CListItemDrawer::EPaintedSelection ); |
|
2543 } |
|
2544 if (iListBoxFlags & EDisableHighlight) |
|
2545 { |
|
2546 iItemDrawer->SetFlags( CListItemDrawer::EDisableHighlight ); |
|
2547 } |
|
2548 |
|
2549 if ( iListBoxExt && iListBoxExt->iSingleClickEnabled ) |
|
2550 { |
|
2551 iListBoxExt->EnableHighlight( EFalse ); |
|
2552 iListBoxExt->ReportCollectionChangedEvent(); |
|
2553 } |
|
2554 |
|
2555 UpdateViewColors(); |
|
2556 UpdateItemDrawerColors(); |
|
2557 _AKNTRACE_FUNC_EXIT; |
|
2558 } |
|
2559 |
|
2560 EXPORT_C void CEikListBox::DrawMatcherCursor() const |
|
2561 { |
|
2562 if (!IsMatchBuffer()) |
|
2563 return; |
|
2564 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
2565 if (ItemExists(currentItemIndex)) |
|
2566 { |
|
2567 if (! iView->ItemIsVisible(currentItemIndex)) |
|
2568 ScrollToMakeItemVisible(currentItemIndex); |
|
2569 iView->DrawMatcherCursor(); |
|
2570 } |
|
2571 } |
|
2572 |
|
2573 EXPORT_C TInt CEikListBox::InterItemGap() |
|
2574 { // static |
|
2575 return KEikListBoxInterItemGap; |
|
2576 } |
|
2577 |
|
2578 |
|
2579 EXPORT_C void CEikListBox::DrawItem( TInt aItemIndex ) const |
|
2580 { |
|
2581 _AKNTRACE_FUNC_ENTER; |
|
2582 if ( !IsReadyToDraw() ) |
|
2583 { |
|
2584 _AKNTRACE_FUNC_EXIT; |
|
2585 return; |
|
2586 } |
|
2587 |
|
2588 __ASSERT_ALWAYS( iView, Panic( EEikPanicListBoxNoView ) ); |
|
2589 |
|
2590 TBool viewScrolled = EFalse; |
|
2591 if ( iView->ItemIsPartiallyVisible( aItemIndex ) || |
|
2592 !iView->ItemIsVisible( aItemIndex ) ) |
|
2593 { |
|
2594 viewScrolled = iView->ScrollToMakeItemVisible( aItemIndex ); |
|
2595 } |
|
2596 |
|
2597 if ( !viewScrolled ) |
|
2598 { |
|
2599 iView->DrawItem( aItemIndex ); |
|
2600 } |
|
2601 else |
|
2602 { |
|
2603 UpdateScrollBarThumbs(); |
|
2604 } |
|
2605 _AKNTRACE_FUNC_EXIT; |
|
2606 } |
|
2607 |
|
2608 |
|
2609 EXPORT_C void CEikListBox::ScrollToMakeItemVisible(TInt aItemIndex) const |
|
2610 { |
|
2611 _AKNTRACE_FUNC_ENTER; |
|
2612 __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView)); |
|
2613 TBool scrollingTookPlace = iView->ScrollToMakeItemVisible(aItemIndex); |
|
2614 if (scrollingTookPlace) |
|
2615 UpdateScrollBarThumbs(); |
|
2616 _AKNTRACE_FUNC_EXIT; |
|
2617 } |
|
2618 |
|
2619 EXPORT_C void CEikListBox::RedrawItem( TInt aItemIndex ) |
|
2620 { |
|
2621 _AKNTRACE_FUNC_ENTER; |
|
2622 if (!IsReadyToDraw()) |
|
2623 { |
|
2624 _AKNTRACE_FUNC_EXIT; |
|
2625 return; |
|
2626 } |
|
2627 __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView)); |
|
2628 if ( iView->ItemIsVisible( aItemIndex ) ) |
|
2629 { |
|
2630 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2631 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
2632 |
|
2633 TBool redraw = !IsBackedUp() && ( transApi == NULL || transApi->EffectsDisabled() ); |
|
2634 #else |
|
2635 TBool redraw = !IsBackedUp(); |
|
2636 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2637 |
|
2638 if ( redraw ) |
|
2639 { |
|
2640 TRect redrawRect( |
|
2641 iView->ItemPos( aItemIndex ), |
|
2642 iItemDrawer->ItemCellSize() ); |
|
2643 redrawRect.Intersection( iView->ViewRect() ); |
|
2644 |
|
2645 Window().Invalidate( redrawRect ); |
|
2646 Window().BeginRedraw( redrawRect ); |
|
2647 } |
|
2648 |
|
2649 iView->DrawItem( aItemIndex ); |
|
2650 |
|
2651 if ( redraw ) |
|
2652 { |
|
2653 Window().EndRedraw(); |
|
2654 } |
|
2655 } |
|
2656 _AKNTRACE_FUNC_EXIT; |
|
2657 } |
|
2658 |
|
2659 EXPORT_C void CEikListBox::ActivateL() |
|
2660 { |
|
2661 _AKNTRACE_FUNC_ENTER; |
|
2662 CCoeControl::ActivateL(); |
|
2663 UpdateScrollBarThumbs(); |
|
2664 |
|
2665 CEikButtonGroupContainer *cba; |
|
2666 MopGetObject(cba); |
|
2667 |
|
2668 if (!cba) |
|
2669 { |
|
2670 _AKNTRACE_FUNC_EXIT; |
|
2671 return; |
|
2672 } |
|
2673 |
|
2674 if (iListBoxFlags & EEnterMarks) |
|
2675 { |
|
2676 // Unfortunately, we need to do this here. It belongs to |
|
2677 // CAknSelectionListDialog, but we need this change also |
|
2678 // to code that does not yet use CAknSelectionListDialog. |
|
2679 TRAP_IGNORE(iAvkonEnv->CreateCbaObserverL(cba, this)); |
|
2680 } |
|
2681 if ( iListBoxExt && iListBoxExt->iMSKObserverEnabled && |
|
2682 ( (iListBoxFlags & EShiftEnterMarks) || |
|
2683 (iListBoxFlags & EEnterMarks) ) ) |
|
2684 { |
|
2685 TRAP_IGNORE(iListBoxExt->CreateMSKObserverL(cba, this)); |
|
2686 TRAP_IGNORE(UpdateMarkUnmarkMSKL()); |
|
2687 } |
|
2688 _AKNTRACE_FUNC_EXIT; |
|
2689 } |
|
2690 |
|
2691 |
|
2692 EXPORT_C void CEikListBox::Draw(const TRect& aRect) const |
|
2693 { |
|
2694 _AKNTRACE_FUNC_ENTER; |
|
2695 // If a parent has a custom gc, draw listbox using that gc |
|
2696 CWindowGc* replacedGc = ReplaceGcWithCustomGc( this ); |
|
2697 |
|
2698 CWindowGc* gc = iItemDrawer->Gc(); |
|
2699 TGulBorder::TColors borderColors; |
|
2700 iBorder.Draw(*gc, Rect(), borderColors); |
|
2701 |
|
2702 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2703 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
2704 if ( transApi ) |
|
2705 { |
|
2706 transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, View()->ViewRect() ); |
|
2707 transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); |
|
2708 } |
|
2709 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2710 |
|
2711 |
|
2712 ClearMargins(); |
|
2713 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2714 if ( transApi ) |
|
2715 { |
|
2716 transApi->StopDrawing(); |
|
2717 } |
|
2718 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2719 iView->Draw(&aRect); |
|
2720 |
|
2721 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2722 if ( transApi ) |
|
2723 { |
|
2724 transApi->EndViewRedraw( aRect ); |
|
2725 } |
|
2726 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2727 |
|
2728 if ( replacedGc ) |
|
2729 { |
|
2730 // Stop using the custom gc |
|
2731 iItemDrawer->SetGc( replacedGc ); |
|
2732 } |
|
2733 _AKNTRACE_FUNC_EXIT; |
|
2734 } |
|
2735 |
|
2736 EXPORT_C void CEikListBox::ClearMargins() const |
|
2737 { |
|
2738 if (!iView->RedrawDisabled()) |
|
2739 { |
|
2740 CWindowGc* gc = iItemDrawer->Gc(); |
|
2741 if (gc) |
|
2742 { |
|
2743 TRect viewRect=iView->ViewRect(); |
|
2744 TRect clientRect; |
|
2745 RestoreClientRectFromViewRect(clientRect); |
|
2746 gc->SetBrushColor(iBackColor); |
|
2747 DrawUtils::ClearBetweenRects(*gc, clientRect, viewRect); |
|
2748 } |
|
2749 } |
|
2750 } |
|
2751 |
|
2752 EXPORT_C void CEikListBox::UpdateScrollBarsL() |
|
2753 { |
|
2754 _AKNTRACE_FUNC_ENTER; |
|
2755 if (!iSBFrame) |
|
2756 { |
|
2757 _AKNTRACE_FUNC_EXIT; |
|
2758 return; |
|
2759 } |
|
2760 TEikScrollBarModel hSbarModel; |
|
2761 TEikScrollBarModel vSbarModel; |
|
2762 TRect rect=iView->ViewRect(); |
|
2763 //#ifdef NOT_NEEDED_IN_SERIES60 |
|
2764 if (!(iListBoxFlags & EScrollBarSizeExcluded)) |
|
2765 { |
|
2766 // Ignore scrollbars presence to set the model, Scrollbar Frame will change it as required |
|
2767 rect = iBorder.InnerRect(Rect()); |
|
2768 rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop, |
|
2769 rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom); |
|
2770 AdjustRectHeightToWholeNumberOfItems(rect); |
|
2771 // rect is now viewRect when ignoring scrollbars |
|
2772 } |
|
2773 //#endif |
|
2774 TInt itemHeight = iView->ItemHeight(); |
|
2775 TSize viewSize( iView->ViewRect().Size() ); |
|
2776 |
|
2777 if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff) |
|
2778 { |
|
2779 if (!(iListBoxFlags & EPageAtOnceScrolling)) |
|
2780 { |
|
2781 if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan) |
|
2782 { |
|
2783 // For EDoubleSpan type scrollbar |
|
2784 vSbarModel.iThumbPosition = iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels(); |
|
2785 } |
|
2786 else |
|
2787 { |
|
2788 // For EArrowHead type scrollbar |
|
2789 vSbarModel.iThumbPosition = iView->CurrentItemIndex(); |
|
2790 } |
|
2791 vSbarModel.iScrollSpan = iModel->NumberOfItems()*iView->ItemHeight(); |
|
2792 } |
|
2793 else |
|
2794 { // Viewer |
|
2795 vSbarModel.iThumbPosition = iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels(); |
|
2796 vSbarModel.iScrollSpan = iModel->NumberOfItems()*iView->ItemHeight(); |
|
2797 } |
|
2798 if ( vSbarModel.iScrollSpan == viewSize.iHeight ) |
|
2799 { |
|
2800 vSbarModel.iThumbSpan = viewSize.iHeight; |
|
2801 } |
|
2802 else |
|
2803 { |
|
2804 vSbarModel.iThumbSpan = viewSize.iHeight - viewSize.iHeight % 2; |
|
2805 } |
|
2806 //#ifdef NOT_NEEDED_IN_SERIES60 |
|
2807 if ( IsActivated() ) |
|
2808 { |
|
2809 if (vSbarModel.iScrollSpan-vSbarModel.iThumbPosition<vSbarModel.iThumbSpan) |
|
2810 { |
|
2811 vSbarModel.iThumbPosition=Max(0,vSbarModel.iScrollSpan-vSbarModel.iThumbSpan); |
|
2812 // This call causes redraw that should not be done in SizeChanged phase. |
|
2813 iView->ScrollToMakeItemVisible(vSbarModel.iThumbPosition/iView->ItemHeight()); // force a scroll if neccessary |
|
2814 } |
|
2815 } |
|
2816 //#endif |
|
2817 } |
|
2818 if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff) |
|
2819 { |
|
2820 iView->CalcDataWidth(); |
|
2821 hSbarModel.iThumbPosition = iView->HScrollOffset(); |
|
2822 hSbarModel.iScrollSpan = iView->DataWidth(); |
|
2823 hSbarModel.iThumbSpan = iView->VisibleWidth(rect); |
|
2824 } |
|
2825 |
|
2826 if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan) |
|
2827 { |
|
2828 // For EDoubleSpan type scrollbar |
|
2829 TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel ); |
|
2830 TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel ); |
|
2831 |
|
2832 TRect clientRect = Rect(); |
|
2833 TRect inclusiveRect = Rect(); |
|
2834 TEikScrollBarFrameLayout layout; |
|
2835 layout.iTilingMode=TEikScrollBarFrameLayout::EInclusiveRectConstant; |
|
2836 layout.SetClientMargin(0); |
|
2837 layout.SetInclusiveMargin(0); |
|
2838 if(iSBFrameOwned == EOwnedExternally) |
|
2839 iSBFrame->Tile(&hDsSbarModel, &vDsSbarModel); |
|
2840 else |
|
2841 { |
|
2842 TBool sizeChanged=EFalse; |
|
2843 sizeChanged=iSBFrame->TileL(&hDsSbarModel, &vDsSbarModel, clientRect, inclusiveRect, layout); |
|
2844 if (sizeChanged) |
|
2845 { |
|
2846 iSBFrame->DrawScrollBarsDeferred(); |
|
2847 } |
|
2848 } |
|
2849 } |
|
2850 else |
|
2851 { |
|
2852 // For EArrowHead type scrollbar |
|
2853 TRect clientRect; |
|
2854 RestoreClientRectFromViewRect(clientRect); |
|
2855 TRect inclusiveRect=Rect(); |
|
2856 TEikScrollBarFrameLayout layout; |
|
2857 CreateScrollBarFrameLayout(layout); |
|
2858 TBool sizeChanged=iSBFrame->TileL(&hSbarModel, &vSbarModel, clientRect, inclusiveRect, layout); |
|
2859 if (iListBoxExt->UpdateScrollBarsColors()) |
|
2860 UpdateScrollBarsColors(); |
|
2861 if (!sizeChanged) |
|
2862 return; |
|
2863 // else size of client/inclusive rect has changed |
|
2864 if (layout.iTilingMode==TEikScrollBarFrameLayout::EClientRectConstant) |
|
2865 SetSizeWithoutNotification(inclusiveRect.Size()); |
|
2866 else |
|
2867 { |
|
2868 SetViewRectFromClientRect(clientRect); |
|
2869 ClearMargins(); |
|
2870 } |
|
2871 } |
|
2872 |
|
2873 if ( iListBoxExt ) |
|
2874 { |
|
2875 iListBoxExt->CheckScrollBarVisibility(); |
|
2876 } |
|
2877 |
|
2878 AdjustTopItemIndex(); |
|
2879 _AKNTRACE_FUNC_EXIT; |
|
2880 } |
|
2881 |
|
2882 EXPORT_C void CEikListBox::CreateScrollBarFrameLayout(TEikScrollBarFrameLayout& aLayout) const |
|
2883 { |
|
2884 _AKNTRACE_FUNC_ENTER; |
|
2885 aLayout.iInclusiveMargin=iBorder.Margins(); |
|
2886 |
|
2887 aLayout.iClientMargin.iTop=ListBoxMargins().iTop; |
|
2888 aLayout.iClientMargin.iBottom=ListBoxMargins().iBottom; |
|
2889 aLayout.iClientMargin.iLeft=ListBoxMargins().iLeft; |
|
2890 aLayout.iClientMargin.iRight=ListBoxMargins().iRight; |
|
2891 |
|
2892 aLayout.iClientAreaGranularity=TSize(HorizScrollGranularityInPixels(), iItemHeight); |
|
2893 aLayout.iTilingMode=(!(iListBoxFlags & EScrollBarSizeExcluded))? TEikScrollBarFrameLayout::EInclusiveRectConstant : TEikScrollBarFrameLayout::EClientRectConstant; |
|
2894 _AKNTRACE_FUNC_EXIT; |
|
2895 } |
|
2896 |
|
2897 EXPORT_C TInt CEikListBox::HorizScrollGranularityInPixels() const |
|
2898 { |
|
2899 return 1; // horiz scroll bar model set in pixels for standard listbox |
|
2900 } |
|
2901 |
|
2902 EXPORT_C void CEikListBox::Reset() |
|
2903 { |
|
2904 _AKNTRACE_FUNC_ENTER; |
|
2905 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
2906 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
2907 if ( transApi ) |
|
2908 { |
|
2909 transApi->Remove( MAknListBoxTfxInternal:: EListEverything ); |
|
2910 } |
|
2911 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
2912 |
|
2913 ((CListBoxView::CSelectionIndexArray*)iView->SelectionIndexes())->Reset(); |
|
2914 iView->SetTopItemIndex(0); |
|
2915 iView->SetCurrentItemIndex(0); |
|
2916 iView->ClearSelectionAnchorAndActiveIndex(); |
|
2917 iView->SetHScrollOffset(0); |
|
2918 |
|
2919 FireItemChange(); |
|
2920 _AKNTRACE_FUNC_EXIT; |
|
2921 } |
|
2922 |
|
2923 EXPORT_C void CEikListBox::AddItemChangeObserverL( |
|
2924 MListBoxItemChangeObserver* aObserver ) |
|
2925 { |
|
2926 _AKNTRACE_FUNC_ENTER; |
|
2927 if( !aObserver ) |
|
2928 { |
|
2929 User::Leave( KErrArgument ); |
|
2930 } |
|
2931 |
|
2932 CheckCreateExtensionL(); |
|
2933 iListBoxExt->AddItemChangeObserverL( aObserver ); |
|
2934 _AKNTRACE_FUNC_EXIT; |
|
2935 } |
|
2936 |
|
2937 EXPORT_C TBool CEikListBox::RemoveItemChangeObserver( |
|
2938 MListBoxItemChangeObserver* aObserver ) |
|
2939 { |
|
2940 _AKNTRACE_FUNC_ENTER; |
|
2941 if( !iListBoxExt ) |
|
2942 { |
|
2943 _AKNTRACE_FUNC_EXIT; |
|
2944 return EFalse; |
|
2945 } |
|
2946 _AKNTRACE_FUNC_EXIT; |
|
2947 return iListBoxExt->RemoveItemChangeObserver( aObserver ); |
|
2948 } |
|
2949 |
|
2950 EXPORT_C void CEikListBox::AddSelectionObserverL( MListBoxSelectionObserver* aObserver ) |
|
2951 { |
|
2952 _AKNTRACE_FUNC_ENTER; |
|
2953 if( !aObserver ) |
|
2954 { |
|
2955 User::Leave( KErrArgument ); |
|
2956 } |
|
2957 |
|
2958 CheckCreateExtensionL(); |
|
2959 iListBoxExt->AddSelectionObserverL( aObserver ); |
|
2960 _AKNTRACE_FUNC_EXIT; |
|
2961 } |
|
2962 |
|
2963 EXPORT_C void CEikListBox::RemoveSelectionObserver( MListBoxSelectionObserver* aObserver ) |
|
2964 { |
|
2965 _AKNTRACE_FUNC_ENTER; |
|
2966 if( iListBoxExt ) |
|
2967 { |
|
2968 iListBoxExt->RemoveSelectionObserver( aObserver ); |
|
2969 } |
|
2970 _AKNTRACE_FUNC_EXIT; |
|
2971 } |
|
2972 |
|
2973 void CEikListBox::ChangeSelectionMode( TBool aEnable ) |
|
2974 // Nonexported helper function. |
|
2975 { |
|
2976 _AKNTRACE_FUNC_ENTER; |
|
2977 // UI Spec does not mention this, but it is reasonable not to |
|
2978 // change selection mode on unmarkable item. |
|
2979 TInt index = CurrentItemIndex(); |
|
2980 if ( index >= 0 && aEnable |
|
2981 && iItemDrawer->Properties(index).IsSelectionHidden() ) |
|
2982 { |
|
2983 _AKNTRACE_FUNC_EXIT; |
|
2984 return; |
|
2985 } |
|
2986 if( !iListBoxExt ) |
|
2987 { |
|
2988 _AKNTRACE_FUNC_EXIT; |
|
2989 return; |
|
2990 } |
|
2991 CEikButtonGroupContainer *bgc; |
|
2992 CCoeControl* MSK( NULL ); |
|
2993 CEikCba* cba( NULL ); |
|
2994 CONST_CAST( CEikListBox*,this )->MopGetObject( bgc ); |
|
2995 if ( !bgc ) |
|
2996 { |
|
2997 _AKNTRACE_FUNC_EXIT; |
|
2998 return; // No bgc -> no cba -> nothing can be done here (and no need to inform observers) |
|
2999 } |
|
3000 |
|
3001 cba = ( static_cast<CEikCba*>( bgc->ButtonGroup() ) ); // downcast from MEikButtonGroup |
|
3002 |
|
3003 if ( !cba ) |
|
3004 { |
|
3005 _AKNTRACE_FUNC_EXIT; |
|
3006 return; // No cba -> nothing can be done here (and no need to inform observers) |
|
3007 } |
|
3008 |
|
3009 MSK = cba->Control( 3 ); // MSK's position is 3 |
|
3010 |
|
3011 TInt newResourceId( NULL ); |
|
3012 if ( MSK && View()->ItemIsSelected( CurrentItemIndex() ) ) |
|
3013 { |
|
3014 newResourceId = R_AVKON_SOFTKEY_UNMARK; |
|
3015 } |
|
3016 if ( MSK && !View()->ItemIsSelected( CurrentItemIndex() ) ) |
|
3017 { |
|
3018 newResourceId = R_AVKON_SOFTKEY_MARK; |
|
3019 } |
|
3020 |
|
3021 if ( aEnable && newResourceId ) |
|
3022 { |
|
3023 TRAPD( err, bgc->AddCommandToStackL( 3, newResourceId ) ); |
|
3024 // in case of error, don't inform observers |
|
3025 // marking still works even MSK isn't changed |
|
3026 if ( err ) |
|
3027 { |
|
3028 iListBoxExt->iSelectionModeEnabled = EFalse; |
|
3029 _AKNTRACE_FUNC_EXIT; |
|
3030 return; |
|
3031 } |
|
3032 cba->DrawNow(); |
|
3033 iListBoxExt->iSelectionModeEnabled = ETrue; |
|
3034 } |
|
3035 |
|
3036 // remove stacked MSK |
|
3037 if( !aEnable && iListBoxExt->iSelectionModeEnabled ) |
|
3038 { |
|
3039 if( ( MSK && cba->ControlId( MSK ) == EAknSoftkeyMark ) || |
|
3040 ( MSK && cba->ControlId( MSK ) == EAknSoftkeyUnmark ) ) |
|
3041 { |
|
3042 bgc->RemoveCommandFromStack( 3, cba->ControlId( MSK ) ); |
|
3043 } |
|
3044 iListBoxExt->iSelectionModeEnabled = EFalse; // just in case |
|
3045 } |
|
3046 |
|
3047 TInt count = iListBoxExt->iSelectionObservers.Count(); |
|
3048 for ( int i=0; i < count; i++ ) |
|
3049 { |
|
3050 iListBoxExt->iSelectionObservers[i]->SelectionModeChanged( this, aEnable ); |
|
3051 } |
|
3052 _AKNTRACE_FUNC_EXIT; |
|
3053 } |
|
3054 |
|
3055 |
|
3056 void CEikListBox::HandleItemRemovalWithoutSelectionsL() |
|
3057 // Nonexported helper function. |
|
3058 { |
|
3059 _AKNTRACE_FUNC_ENTER; |
|
3060 // this will force update of physics parameters next time when list is panned |
|
3061 iView->SetItemOffsetInPixels( 0 ); |
|
3062 iView->SetFlags(CListBoxView::EItemCountModified); |
|
3063 iView->CalcDataWidth(); |
|
3064 iView->CalcBottomItemIndex(); |
|
3065 UpdateScrollBarsL(); |
|
3066 UpdateScrollBarThumbs(); |
|
3067 iView->ClearFlags(CListBoxView::EItemCountModified); |
|
3068 |
|
3069 FireItemChange(); |
|
3070 |
|
3071 if ( iListBoxExt && iListBoxExt->iPhysics ) |
|
3072 { |
|
3073 iListBoxExt->InitPhysicsL(); |
|
3074 } |
|
3075 _AKNTRACE_FUNC_EXIT; |
|
3076 } |
|
3077 |
|
3078 EXPORT_C void CEikListBox::HandleItemRemovalL(CArrayFix<TInt> &aArrayOfOldIndexes) |
|
3079 // NOTE, This algorithm cannot handle position of the list highlight |
|
3080 // nor can it update the topitemindex correctly. |
|
3081 { |
|
3082 _AKNTRACE_FUNC_ENTER; |
|
3083 TKeyArrayFix key(0,ECmpTInt); |
|
3084 aArrayOfOldIndexes.Sort(key); |
|
3085 |
|
3086 // remove removed items from selection index array |
|
3087 TInt changedcount = aArrayOfOldIndexes.Count(); |
|
3088 for(TInt iii=0;iii<changedcount;iii++) |
|
3089 { |
|
3090 iView->DeselectItem(aArrayOfOldIndexes.At(iii)); |
|
3091 } |
|
3092 |
|
3093 // decrease selectionindexes. Does not change their order, so resorting |
|
3094 // the array is not necessary |
|
3095 CListBoxView::CSelectionIndexArray* array = CONST_CAST(CListBoxView::CSelectionIndexArray*,iView->SelectionIndexes()); |
|
3096 TInt selectioncount = array->Count(); |
|
3097 TInt removedcount = aArrayOfOldIndexes.Count(); |
|
3098 for(TInt ii = 0;ii<removedcount;ii++) |
|
3099 { |
|
3100 for(TInt i=0;i<selectioncount;i++) |
|
3101 { |
|
3102 // since we deselected the item, its not possible that |
|
3103 // the removed item is still in selectionindexes array. |
|
3104 __ASSERT_DEBUG(array->At(i) != aArrayOfOldIndexes.At(ii), Panic(EEikPanicOutOfRange)); |
|
3105 if (array->At(i) > aArrayOfOldIndexes.At(ii)) |
|
3106 { |
|
3107 (*array)[i]-=1; |
|
3108 } |
|
3109 } |
|
3110 } |
|
3111 |
|
3112 HandleItemRemovalWithoutSelectionsL(); |
|
3113 _AKNTRACE_FUNC_EXIT; |
|
3114 } |
|
3115 |
|
3116 EXPORT_C void CEikListBox::HandleItemAdditionL(CArrayFix<TInt> &aArrayOfNewIndexesAfterAddition) |
|
3117 // NOTE, This algorithm cannot handle position of the list highlight |
|
3118 // nor can it update the topitemindex correctly. |
|
3119 { |
|
3120 _AKNTRACE_FUNC_ENTER; |
|
3121 // Updates selectionindexes array |
|
3122 |
|
3123 // Sort indexes first |
|
3124 TKeyArrayFix key(0,ECmpTInt); |
|
3125 aArrayOfNewIndexesAfterAddition.Sort(key); |
|
3126 |
|
3127 // increase selectionindexes. |
|
3128 CListBoxView::CSelectionIndexArray* array = CONST_CAST(CListBoxView::CSelectionIndexArray*,iView->SelectionIndexes()); |
|
3129 TInt selectioncount = array->Count(); |
|
3130 TInt newindexcount = aArrayOfNewIndexesAfterAddition.Count(); |
|
3131 for(TInt ii = 0;ii<newindexcount;ii++) |
|
3132 { |
|
3133 for(TInt i=0;i<selectioncount;i++) |
|
3134 { |
|
3135 if (array->At(i) >= aArrayOfNewIndexesAfterAddition.At(ii)) |
|
3136 { |
|
3137 (*array)[i]+=1; |
|
3138 } |
|
3139 } |
|
3140 } |
|
3141 |
|
3142 // other features that does not depend on the items added. |
|
3143 HandleItemAdditionL(); |
|
3144 _AKNTRACE_FUNC_EXIT; |
|
3145 } |
|
3146 |
|
3147 EXPORT_C void CEikListBox::HandleItemAdditionL() |
|
3148 { |
|
3149 _AKNTRACE_FUNC_ENTER; |
|
3150 //fix the bug EGGO-7SQA4S and EVSG-7TD9WZ |
|
3151 TInt curItemIndex = iView->CurrentItemIndex(); |
|
3152 if(curItemIndex >= 0 && curItemIndex < iModel->NumberOfItems() ) |
|
3153 { |
|
3154 TInt newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( curItemIndex ); |
|
3155 iView->SetTopItemIndex( newTopItemIndex ); |
|
3156 } |
|
3157 iView->SetFlags(CListBoxView::EItemCountModified); |
|
3158 // following breaks lists in square layout, not needed in SERIES60? |
|
3159 //iView->CalcDataWidth(); |
|
3160 iView->CalcBottomItemIndex(); |
|
3161 UpdateScrollBarsL(); |
|
3162 UpdateScrollBarThumbs(); |
|
3163 if (IsReadyToDraw()) DrawDeferred(); |
|
3164 iView->ClearFlags(CListBoxView::EItemCountModified); |
|
3165 |
|
3166 FireItemChange(); |
|
3167 |
|
3168 if ( iListBoxExt ) |
|
3169 { |
|
3170 iListBoxExt->CheckScrollBarVisibility(); |
|
3171 // Physics engine world size needs to be updated here, otherwise aknphysics |
|
3172 // cone observer may block pointer events on new items. this can happen |
|
3173 // when item addition inserts new row to taskswapper's grid and reuses list in Common Dialog |
|
3174 if ( iListBoxExt->iPhysics ) |
|
3175 { |
|
3176 iListBoxExt->InitPhysicsL(); |
|
3177 } |
|
3178 } |
|
3179 _AKNTRACE_FUNC_EXIT; |
|
3180 } |
|
3181 |
|
3182 EXPORT_C void CEikListBox::HandleItemRemovalL() |
|
3183 { |
|
3184 // Should be called after one or more items have been removed from the model |
|
3185 // It is up to the application to then make sure that the current item index is set to an appropriate value and to redraw the listbox |
|
3186 _AKNTRACE_FUNC_ENTER; |
|
3187 ((CListBoxView::CSelectionIndexArray*)iView->SelectionIndexes())->Reset(); |
|
3188 HandleItemRemovalWithoutSelectionsL(); |
|
3189 _AKNTRACE_FUNC_EXIT; |
|
3190 // Please do not add anything here. Add them to the HandleItemRemovalWithoutSelectionsL(). |
|
3191 } |
|
3192 |
|
3193 EXPORT_C const CArrayFix<TInt>* CEikListBox::SelectionIndexes() const |
|
3194 { |
|
3195 return iView->SelectionIndexes(); |
|
3196 } |
|
3197 |
|
3198 EXPORT_C void CEikListBox::SetSelectionIndexesL(CListBoxView::CSelectionIndexArray* aArrayOfSelectionIndexes) |
|
3199 { |
|
3200 if (! aArrayOfSelectionIndexes) |
|
3201 iView->ClearSelection(); |
|
3202 else |
|
3203 iView->SetSelectionIndexesL(aArrayOfSelectionIndexes); |
|
3204 } |
|
3205 |
|
3206 void CEikListBox::HorizontalScroll(TInt aScrollAmountInPixels) |
|
3207 { |
|
3208 iView->HScroll(aScrollAmountInPixels); |
|
3209 if (iSBFrame) |
|
3210 { |
|
3211 if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff) |
|
3212 iSBFrame->MoveThumbsBy(aScrollAmountInPixels, 0); |
|
3213 } |
|
3214 } |
|
3215 |
|
3216 EXPORT_C void CEikListBox::HandleLeftArrowKeyL(CListBoxView::TSelectionMode /*aSelectionMode*/) |
|
3217 { |
|
3218 HorizontalScroll(-(iView->ViewRect().Width() / KEikListBoxHNudgeSizeAsFractionOfViewRectWidth)); |
|
3219 } |
|
3220 |
|
3221 |
|
3222 EXPORT_C void CEikListBox::HandleRightArrowKeyL(CListBoxView::TSelectionMode /*aSelectionMode*/) |
|
3223 { |
|
3224 HorizontalScroll((iView->ViewRect().Width() / KEikListBoxHNudgeSizeAsFractionOfViewRectWidth)); |
|
3225 } |
|
3226 //#define KEY_DEBUG |
|
3227 |
|
3228 #if defined(_DEBUG) && defined(KEY_DEBUG) |
|
3229 #define __KeyDebug(b,text) { _LIT(blah, "LbxKeys %d:%d:%c%c%c " ## L ## text); RDebug::Print(blah, aKeyEvent.iCode, aKeyEvent.iScanCode, shiftKeyPressed ? 's' : '_', enterKeyPressed ? 'e' : '_', aType == EEventKey ? 'K' : (aType == EEventKeyDown ? 'D' : (aType == EEventKeyUp ? 'U' : '_'))); } |
|
3230 #else |
|
3231 #define __KeyDebug(b,text) |
|
3232 #endif |
|
3233 |
|
3234 |
|
3235 EXPORT_C TKeyResponse CEikListBox::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
3236 { |
|
3237 _AKNTRACE_FUNC_ENTER; |
|
3238 TKeyEvent keyEvent=aKeyEvent; |
|
3239 keyEvent.iCode=LafListBox::MapKeyCode(aKeyEvent,aType); |
|
3240 _AKNTRACE_FUNC_EXIT; |
|
3241 return DoOfferKeyEventL(keyEvent,aType); |
|
3242 } |
|
3243 |
|
3244 TBool IsSelectionMarkKeys(TInt aCode, TInt aScanCode, TBool aWesternVariant) |
|
3245 { |
|
3246 return aCode == EKeyUpArrow || |
|
3247 aCode == EKeyDownArrow || |
|
3248 aCode == EKeyOK || |
|
3249 /* aCode == EKeyEnter || */ |
|
3250 (aCode == 0 && aScanCode == EStdKeyLeftShift) || |
|
3251 (aCode == 0 && aScanCode == EStdKeyRightShift) || |
|
3252 (aCode == 0 && aScanCode == EStdKeyRightCtrl) || |
|
3253 (!aWesternVariant && (aCode == 0 && aScanCode == EStdKeyHash)); |
|
3254 } |
|
3255 |
|
3256 TKeyResponse CEikListBox::DoOfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
3257 { |
|
3258 _AKNTRACE_FUNC_ENTER; |
|
3259 TInt topItemIndex = iView->TopItemIndex(); |
|
3260 if (ItemExists(topItemIndex) == EFalse) |
|
3261 { |
|
3262 return (aKeyEvent.iScanCode == EStdKeyYes ? EKeyWasNotConsumed:EKeyWasConsumed); |
|
3263 } |
|
3264 |
|
3265 TInt code = aKeyEvent.iCode; |
|
3266 |
|
3267 // With single click first key event enables highlight |
|
3268 if ( iListBoxExt && iListBoxExt->EnableHighlightWithKeyEventL( |
|
3269 topItemIndex, aKeyEvent, aType ) ) |
|
3270 { |
|
3271 _AKNTRACE_FUNC_EXIT; |
|
3272 return EKeyWasConsumed; |
|
3273 } |
|
3274 |
|
3275 (void)aType; // to prevent a warning. |
|
3276 |
|
3277 TBool shiftKeyPressed = (aKeyEvent.iModifiers & EModifierShift) || |
|
3278 (aKeyEvent.iModifiers & EModifierLeftShift) || |
|
3279 (aKeyEvent.iModifiers & EModifierRightShift); |
|
3280 |
|
3281 // Downpressed hash key already generates shift modifier and |
|
3282 // in Chinese variant hash (shift) + movement/MSK should not mark |
|
3283 if ( iListBoxExt && |
|
3284 iListBoxExt->iWesternVariant == EFalse && |
|
3285 iListBoxExt->iAknFepHashKeySelection ) |
|
3286 { |
|
3287 shiftKeyPressed = EFalse; |
|
3288 } |
|
3289 |
|
3290 TBool controlKeyPressed = (aKeyEvent.iModifiers & EModifierCtrl) || |
|
3291 (aKeyEvent.iModifiers & EModifierRightCtrl); |
|
3292 TInt oldCurrentItemIndex = iView->CurrentItemIndex(); |
|
3293 |
|
3294 TBool enterKeyPressed=EFalse; |
|
3295 TBool escapeKeyPressed=EFalse; |
|
3296 TBool sideBarKeyPressed=EFalse; |
|
3297 TBool switchMSK=EFalse; // for mark/unmark in selection lists |
|
3298 |
|
3299 // if we have markable list and either shift, ctrl or hash is long pressed |
|
3300 // down, we will enter selection (marking) mode, where MSK is Mark/Unmark |
|
3301 if( iListBoxExt && (iListBoxFlags & EMultipleSelection) && |
|
3302 (iListBoxFlags & EShiftEnterMarks) && |
|
3303 aType == EEventKeyDown && |
|
3304 ( (iListBoxExt->iWesternVariant && |
|
3305 iListBoxExt->iAknFepHashKeySelection && |
|
3306 iListBoxExt->iQwertyMode == EFalse && |
|
3307 aKeyEvent.iScanCode == EStdKeyHash) || |
|
3308 aKeyEvent.iScanCode == EStdKeyLeftShift || |
|
3309 aKeyEvent.iScanCode == EStdKeyRightShift || |
|
3310 aKeyEvent.iScanCode == EStdKeyLeftCtrl || |
|
3311 aKeyEvent.iScanCode == EStdKeyRightCtrl ) ) |
|
3312 { |
|
3313 iListBoxExt->StartLongPressTimerL(); |
|
3314 iListBoxExt->iShortHashMark = ETrue; |
|
3315 iListBoxExt->iShiftKeyPressed = ETrue; |
|
3316 } |
|
3317 |
|
3318 if( iListBoxExt && (iListBoxFlags & EMultipleSelection) && |
|
3319 (iListBoxFlags & EShiftEnterMarks) && |
|
3320 aType == EEventKeyUp && |
|
3321 ( (iListBoxExt->iWesternVariant && |
|
3322 iListBoxExt->iAknFepHashKeySelection && |
|
3323 iListBoxExt->iQwertyMode == EFalse && |
|
3324 aKeyEvent.iScanCode == EStdKeyHash) || |
|
3325 aKeyEvent.iScanCode == EStdKeyLeftShift || |
|
3326 aKeyEvent.iScanCode == EStdKeyRightShift || |
|
3327 aKeyEvent.iScanCode == EStdKeyLeftCtrl || |
|
3328 aKeyEvent.iScanCode == EStdKeyRightCtrl ) ) |
|
3329 { |
|
3330 iListBoxExt->iShiftKeyPressed = EFalse; |
|
3331 if ( iListBoxExt->iLongPressTimer && |
|
3332 iListBoxExt->iLongPressTimer->IsActive() ) |
|
3333 { |
|
3334 iListBoxExt->iLongPressTimer->Cancel(); |
|
3335 } |
|
3336 if( iListBoxExt->iSelectionModeEnabled ) |
|
3337 { |
|
3338 ChangeSelectionMode( EFalse ); |
|
3339 iListBoxExt->iSelectionModeEnabled = EFalse; |
|
3340 View()->ClearSelectionAnchorAndActiveIndex(); |
|
3341 } |
|
3342 } |
|
3343 |
|
3344 |
|
3345 // SERIES60 LAF |
|
3346 CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection; |
|
3347 if (iListBoxFlags & EMultipleSelection) |
|
3348 { |
|
3349 if ((shiftKeyPressed || controlKeyPressed) && iListBoxFlags & EShiftEnterMarks && aType == EEventKey) |
|
3350 { |
|
3351 __KeyDebug(ETrue, "shift + enter marks"); |
|
3352 View()->SetAnchor(View()->CurrentItemIndex()); |
|
3353 selectionMode = CListBoxView::EDisjointMarkSelection; |
|
3354 } |
|
3355 else |
|
3356 { |
|
3357 selectionMode = CListBoxView::ENoSelection; |
|
3358 UpdateMarkUnmarkMSKL(); |
|
3359 if (IsSelectionMarkKeys(code, aKeyEvent.iScanCode, iListBoxExt->iWesternVariant)) |
|
3360 { |
|
3361 __KeyDebug(ETrue, "SelectionMarkKey") |
|
3362 View()->ClearSelectionAnchorAndActiveIndex(); |
|
3363 } |
|
3364 } |
|
3365 } |
|
3366 |
|
3367 |
|
3368 // CAknGrid marking is implemeted in avkon.dll. But we still need to disable short |
|
3369 // hash mark in here. |
|
3370 if ( iListBoxFlags & EMultipleSelection && |
|
3371 iListBoxFlags & EShiftEnterMarks && aType == EEventKeyUp ) |
|
3372 { |
|
3373 if ( aKeyEvent.iScanCode == EStdKeyLeftArrow || |
|
3374 aKeyEvent.iScanCode == EStdKeyUpArrow || |
|
3375 aKeyEvent.iScanCode == EStdKeyRightArrow || |
|
3376 aKeyEvent.iScanCode == EStdKeyDownArrow ) |
|
3377 { |
|
3378 iListBoxExt->iShortHashMark = EFalse; |
|
3379 } |
|
3380 // for some applications this is the only way to catch marking with MSK |
|
3381 if ( aKeyEvent.iScanCode == EStdKeyDevice3 ) |
|
3382 { |
|
3383 iListBoxExt->iShortHashMark = EFalse; |
|
3384 } |
|
3385 } |
|
3386 |
|
3387 |
|
3388 TInt oldMatcherCursorPos = iView->MatcherCursorPos(); |
|
3389 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3390 // LISTBOX EFFECTS IMPLEMENTATION |
|
3391 // |
|
3392 // Fetch internal listbox transition API. |
|
3393 // |
|
3394 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
3395 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
3396 |
|
3397 switch (code) |
|
3398 { |
|
3399 case EKeyPrevious: |
|
3400 { |
|
3401 _AKNTRACE( "EKeyPrevious" ); |
|
3402 const TBool disableRedraw = aKeyEvent.iRepeats; |
|
3403 |
|
3404 TBool redrawDisabled = iView->RedrawDisabled(); |
|
3405 if ( disableRedraw ) |
|
3406 { |
|
3407 iView->SetDisableRedraw(ETrue); |
|
3408 } |
|
3409 |
|
3410 TInt count = 1 + aKeyEvent.iRepeats; |
|
3411 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
3412 if( ( currentItemIndex - count) < 0) |
|
3413 { |
|
3414 count = currentItemIndex; |
|
3415 // moveto = CListBoxView::ECursorLastItem; |
|
3416 } |
|
3417 if ( !count ) |
|
3418 { |
|
3419 count = 1; |
|
3420 } |
|
3421 |
|
3422 |
|
3423 for ( TInt ii = 0; ii < count; ii++ ) |
|
3424 { |
|
3425 CListBoxView::TCursorMovement moveto = CListBoxView::ECursorPreviousItem; |
|
3426 if (iListBoxFlags & EPageAtOnceScrolling) |
|
3427 { |
|
3428 moveto = CListBoxView::ECursorPrevScreen; |
|
3429 } |
|
3430 |
|
3431 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
3432 if(!(iListBoxFlags & EPopout) && (currentItemIndex==0 || currentItemIndex==-1)) |
|
3433 { |
|
3434 if (iListBoxFlags & ELoopScrolling) |
|
3435 { |
|
3436 moveto = CListBoxView::ECursorLastItem; |
|
3437 } |
|
3438 else |
|
3439 { |
|
3440 break; |
|
3441 } |
|
3442 } |
|
3443 iView->MoveCursorL(moveto, selectionMode); |
|
3444 ClearMatchBuffer(); |
|
3445 } |
|
3446 |
|
3447 if ( disableRedraw ) |
|
3448 { |
|
3449 iView->SetDisableRedraw(redrawDisabled); |
|
3450 if ( !redrawDisabled ) |
|
3451 { |
|
3452 DrawNow(); |
|
3453 } |
|
3454 } |
|
3455 |
|
3456 if (iListBoxFlags & EMultipleSelection) |
|
3457 { |
|
3458 switchMSK = ETrue; // we need to check MSK later |
|
3459 } |
|
3460 } |
|
3461 if(AknLayoutUtils::PenEnabled()) |
|
3462 { |
|
3463 // update scroll bar thumbs here, because it is needed when scrolled. |
|
3464 UpdateScrollBarThumbs(); |
|
3465 } |
|
3466 break; |
|
3467 case EKeyNext: |
|
3468 { |
|
3469 _AKNTRACE( "EKeyNext" ); |
|
3470 const TBool disableRedraw = aKeyEvent.iRepeats; |
|
3471 TBool redrawDisabled = iView->RedrawDisabled(); |
|
3472 if ( disableRedraw ) |
|
3473 { |
|
3474 iView->SetDisableRedraw(ETrue); |
|
3475 } |
|
3476 |
|
3477 TInt count = 1 + aKeyEvent.iRepeats; |
|
3478 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
3479 if(currentItemIndex + count > Model()->NumberOfItems()-1 ) |
|
3480 { |
|
3481 count = ( Model()->NumberOfItems() - 1 ) - currentItemIndex; |
|
3482 } |
|
3483 if ( !count ) |
|
3484 { |
|
3485 count = 1; |
|
3486 } |
|
3487 |
|
3488 |
|
3489 for ( TInt ii = 0; ii < count; ii++ ) |
|
3490 { |
|
3491 CListBoxView::TCursorMovement moveto = CListBoxView::ECursorNextItem; |
|
3492 if (iListBoxFlags & EPageAtOnceScrolling) |
|
3493 { |
|
3494 moveto = CListBoxView::ECursorNextScreen; |
|
3495 } |
|
3496 |
|
3497 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
3498 if(!(iListBoxFlags & EPopout) && |
|
3499 (currentItemIndex==Model()->NumberOfItems()-1 || currentItemIndex==-1)) |
|
3500 { |
|
3501 if (iListBoxFlags & ELoopScrolling) |
|
3502 { |
|
3503 moveto = CListBoxView::ECursorFirstItem; |
|
3504 } |
|
3505 else |
|
3506 { |
|
3507 break; |
|
3508 } |
|
3509 } |
|
3510 iView->MoveCursorL(moveto, selectionMode); |
|
3511 ClearMatchBuffer(); |
|
3512 } |
|
3513 |
|
3514 if ( disableRedraw ) |
|
3515 { |
|
3516 iView->SetDisableRedraw(redrawDisabled); |
|
3517 if ( !redrawDisabled ) |
|
3518 { |
|
3519 DrawNow(); |
|
3520 } |
|
3521 } |
|
3522 |
|
3523 if (iListBoxFlags & EMultipleSelection) |
|
3524 { |
|
3525 switchMSK = ETrue; // we need to check MSK later |
|
3526 } |
|
3527 } |
|
3528 if(AknLayoutUtils::PenEnabled()) |
|
3529 { |
|
3530 // update scroll bar thumbs here, because it is needed when scrolled. |
|
3531 UpdateScrollBarThumbs(); |
|
3532 } |
|
3533 break; |
|
3534 case EKeyApplicationF: |
|
3535 // avkonenv can send these events to listbox. |
|
3536 // CR PKEA-4YSASZ |
|
3537 _AKNTRACE( "EKeyApplicationF" ); |
|
3538 if (SelectionIndexes()->Count()==0) |
|
3539 { |
|
3540 TInt currentItem = View()->CurrentItemIndex(); |
|
3541 if (currentItem >= 0) |
|
3542 { |
|
3543 View()->SelectItemL(currentItem); |
|
3544 } |
|
3545 } |
|
3546 _AKNTRACE_FUNC_EXIT; |
|
3547 return EKeyWasConsumed; |
|
3548 case EKeyUpArrow: |
|
3549 { |
|
3550 _AKNTRACE( "EKeyUpArrow" ); |
|
3551 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3552 // LISTBOX EFFECTS IMPLEMENTATION |
|
3553 // |
|
3554 // Set type of momement |
|
3555 // |
|
3556 if ( transApi ) |
|
3557 { |
|
3558 transApi->SetMoveType( MAknListBoxTfxInternal::EListMoveUp ); |
|
3559 } |
|
3560 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
3561 |
|
3562 // Note, in Series 60 we always eat uparrow and downarrow |
|
3563 // in lists, even though it does not really change list state. |
|
3564 CListBoxView::TCursorMovement moveto = CListBoxView::ECursorPreviousItem; |
|
3565 if (iListBoxFlags & EPageAtOnceScrolling) |
|
3566 { |
|
3567 moveto = CListBoxView::ECursorPrevScreen; |
|
3568 } |
|
3569 if(!(iListBoxFlags & EPopout) && (oldCurrentItemIndex==0 || oldCurrentItemIndex==-1)) |
|
3570 { |
|
3571 if (iListBoxFlags& ELoopScrolling) |
|
3572 { |
|
3573 moveto = CListBoxView::ECursorLastItem; |
|
3574 } |
|
3575 else if ( ScrollingDisabled() && topItemIndex == 0 ) |
|
3576 { |
|
3577 _AKNTRACE_FUNC_EXIT; |
|
3578 return( EKeyWasConsumed ); |
|
3579 } |
|
3580 } |
|
3581 |
|
3582 if ( ScrollingDisabled() || ( !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) ) |
|
3583 { |
|
3584 iView->MoveCursorL(moveto, selectionMode); |
|
3585 } |
|
3586 ClearMatchBuffer(); |
|
3587 if( iListBoxFlags & EMultipleSelection ) |
|
3588 { |
|
3589 switchMSK = ETrue; // we need to check MSK later |
|
3590 } |
|
3591 } |
|
3592 if( AknLayoutUtils::PenEnabled() ) |
|
3593 { |
|
3594 // update scroll bar thumbs here, because it is needed when scrolled. |
|
3595 UpdateScrollBarThumbs(); |
|
3596 } |
|
3597 break; |
|
3598 case EKeyDownArrow: |
|
3599 { |
|
3600 _AKNTRACE( "EKeyDownArrow" ); |
|
3601 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
3602 // LISTBOX EFFECTS IMPLEMENTATION |
|
3603 // |
|
3604 // Set type of momement |
|
3605 // |
|
3606 if ( transApi ) |
|
3607 { |
|
3608 transApi->SetMoveType( MAknListBoxTfxInternal::EListMoveDown ); |
|
3609 } |
|
3610 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
3611 |
|
3612 CListBoxView::TCursorMovement moveto = CListBoxView::ECursorNextItem; |
|
3613 if (iListBoxFlags & EPageAtOnceScrolling) |
|
3614 { |
|
3615 moveto = CListBoxView::ECursorNextScreen; |
|
3616 } |
|
3617 if(!(iListBoxFlags & EPopout) && |
|
3618 (oldCurrentItemIndex==Model()->NumberOfItems()-1 || oldCurrentItemIndex==-1)) |
|
3619 { |
|
3620 if (iListBoxFlags & ELoopScrolling) |
|
3621 { |
|
3622 moveto = CListBoxView::ECursorFirstItem; |
|
3623 } |
|
3624 else if ( ScrollingDisabled() && ( topItemIndex != 0 ) ) |
|
3625 { |
|
3626 _AKNTRACE_FUNC_EXIT; |
|
3627 return(EKeyWasConsumed); |
|
3628 } |
|
3629 } |
|
3630 |
|
3631 if ( ScrollingDisabled() || ( !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) ) |
|
3632 { |
|
3633 iView->MoveCursorL(moveto, selectionMode); |
|
3634 } |
|
3635 ClearMatchBuffer(); |
|
3636 if (iListBoxFlags & EMultipleSelection) |
|
3637 { |
|
3638 switchMSK = ETrue; // we need to check MSK later |
|
3639 } |
|
3640 } |
|
3641 if(AknLayoutUtils::PenEnabled()) |
|
3642 { |
|
3643 // update scroll bar thumbs here, because it is needed when scrolled. |
|
3644 UpdateScrollBarThumbs(); |
|
3645 } |
|
3646 break; |
|
3647 case EKeyEnter: |
|
3648 case EKeyOK: |
|
3649 { |
|
3650 _AKNTRACE( "EKeyEnter or EKeyOK" ); |
|
3651 if (aKeyEvent.iRepeats != 0) |
|
3652 { |
|
3653 break; |
|
3654 } |
|
3655 // Series 60 case where ok or shift+ok is pressed |
|
3656 if (iListBoxFlags & EMultipleSelection) |
|
3657 { |
|
3658 if ((shiftKeyPressed || controlKeyPressed) && iListBoxFlags & EShiftEnterMarks |
|
3659 || iListBoxFlags & EEnterMarks) |
|
3660 { |
|
3661 __KeyDebug(ETrue, "shift+ok or ok in markable/multiselection"); |
|
3662 |
|
3663 iView->UpdateSelectionL(CListBoxView::EDisjointSelection); |
|
3664 iListBoxFlags |= EStateChanged; |
|
3665 switchMSK = ETrue; |
|
3666 break; |
|
3667 } |
|
3668 |
|
3669 // Markable list CR JLEO-4VQJ75 |
|
3670 if (!shiftKeyPressed && iListBoxFlags & EShiftEnterMarks) |
|
3671 { |
|
3672 // enter key pressed on markable list without shift |
|
3673 if (SelectionIndexes()->Count() > 0) |
|
3674 { |
|
3675 // when there's marked items, should open options menu. |
|
3676 __KeyDebug(ETrue, "ok without shift => ok options menu"); |
|
3677 |
|
3678 CEikMenuBar *bar; |
|
3679 MopGetObject(bar); |
|
3680 if (bar) |
|
3681 { |
|
3682 bar->TryDisplayMenuBarL(); |
|
3683 } |
|
3684 _AKNTRACE_FUNC_EXIT; |
|
3685 return EKeyWasConsumed; |
|
3686 } |
|
3687 } |
|
3688 } |
|
3689 |
|
3690 // Series 60 ok key |
|
3691 __KeyDebug(ETrue, "open item"); |
|
3692 enterKeyPressed = ETrue; |
|
3693 } |
|
3694 break; |
|
3695 default: |
|
3696 if (iListBoxFlags & EIncrementalMatching) |
|
3697 { |
|
3698 if (TChar(aKeyEvent.iCode).IsPrint()) |
|
3699 { |
|
3700 MatchTypedCharL(aKeyEvent.iCode); |
|
3701 } |
|
3702 else |
|
3703 { |
|
3704 _AKNTRACE_FUNC_EXIT; |
|
3705 return (aKeyEvent.iScanCode == EStdKeyYes ? |
|
3706 EKeyWasNotConsumed : EKeyWasConsumed); |
|
3707 } |
|
3708 } |
|
3709 break; |
|
3710 } |
|
3711 // |
|
3712 // Switch/case ends here |
|
3713 // |
|
3714 if(switchMSK) |
|
3715 { |
|
3716 if( selectionMode == CListBoxView::EDisjointMarkSelection ) |
|
3717 { |
|
3718 // if hash and either up or down pressed -> no short marking |
|
3719 iListBoxExt->iShortHashMark = EFalse; |
|
3720 } |
|
3721 UpdateMarkUnmarkMSKL(); |
|
3722 } |
|
3723 |
|
3724 if(!AknLayoutUtils::PenEnabled()) |
|
3725 { |
|
3726 // do update only when needed and in correct place. (prevents flicker). |
|
3727 // This place is called three times for every button event (down, key-event and up) |
|
3728 UpdateScrollBarThumbs(); |
|
3729 } |
|
3730 |
|
3731 if (oldCurrentItemIndex != iView->CurrentItemIndex()) |
|
3732 { |
|
3733 iListBoxFlags |= EStateChanged; |
|
3734 DrawMatcherCursor(); |
|
3735 } |
|
3736 else if (oldMatcherCursorPos != iView->MatcherCursorPos() && IsMatchBuffer()) |
|
3737 { |
|
3738 DrawMatcherCursor(); |
|
3739 } |
|
3740 |
|
3741 if (iListBoxFlags & EStateChanged) |
|
3742 { |
|
3743 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
3744 iListBoxFlags &= (~EStateChanged); |
|
3745 } |
|
3746 |
|
3747 if (enterKeyPressed) |
|
3748 { |
|
3749 ReportListBoxEventL(MEikListBoxObserver::EEventEnterKeyPressed); |
|
3750 if (iListBoxFlags & EPopout) |
|
3751 { |
|
3752 ReportEventL(MCoeControlObserver::EEventRequestExit); |
|
3753 } |
|
3754 } |
|
3755 |
|
3756 if (escapeKeyPressed || sideBarKeyPressed) |
|
3757 { |
|
3758 if (iListBoxFlags & EPopout) |
|
3759 { |
|
3760 ReportEventL(MCoeControlObserver::EEventRequestCancel); |
|
3761 } |
|
3762 } |
|
3763 |
|
3764 if (sideBarKeyPressed) |
|
3765 { |
|
3766 _AKNTRACE_FUNC_EXIT; |
|
3767 return(EKeyWasNotConsumed); |
|
3768 } |
|
3769 |
|
3770 // This code block watches for hash key presses, and simulates shift + ok |
|
3771 // if short hash key presses are used for selections. The events are simulated |
|
3772 // only if a markable list is active, otherwise the simulated event might open |
|
3773 // the selected item, which we don't want. |
|
3774 if((iListBoxFlags & EMultipleSelection) && (iListBoxFlags & EShiftEnterMarks) && |
|
3775 iListBoxExt->iWesternVariant && |
|
3776 iListBoxExt->iAknFepHashKeySelection && |
|
3777 iListBoxExt->iQwertyMode == EFalse && |
|
3778 aType == EEventKeyUp && aKeyEvent.iScanCode == EStdKeyHash && |
|
3779 IsFocused() ) |
|
3780 { |
|
3781 if( iListBoxExt->iShortHashMark ) |
|
3782 { |
|
3783 TKeyEvent keyEvent; |
|
3784 keyEvent.iCode = EKeyDevice3; |
|
3785 keyEvent.iScanCode = EStdKeyDevice3; |
|
3786 keyEvent.iRepeats = 0; |
|
3787 keyEvent.iModifiers = EModifierShift; |
|
3788 CCoeEnv::Static()->SimulateKeyEventL(keyEvent, EEventKey); |
|
3789 } |
|
3790 else |
|
3791 { |
|
3792 // some items has been un/marked with hash+up or down |
|
3793 // so don't do short hash mark - just clear selection mode |
|
3794 View()->ClearSelectionAnchorAndActiveIndex(); |
|
3795 } |
|
3796 } |
|
3797 |
|
3798 if ( aKeyEvent.iScanCode == EStdKeyYes ) |
|
3799 { |
|
3800 _AKNTRACE( "EStdKeyYes" ); |
|
3801 _AKNTRACE_FUNC_EXIT; |
|
3802 return EKeyWasNotConsumed; |
|
3803 } |
|
3804 _AKNTRACE_FUNC_EXIT; |
|
3805 return(EKeyWasConsumed); |
|
3806 } |
|
3807 |
|
3808 void CEikListBox::UpdateMarkUnmarkMSKL() const |
|
3809 { |
|
3810 // for markable lists if MSK is either mark/unmark |
|
3811 // and highlighted item has changed, try to switch |
|
3812 // MSK according to item's selection state |
|
3813 _AKNTRACE_FUNC_ENTER; |
|
3814 CEikButtonGroupContainer *bgc; |
|
3815 CCoeControl* MSK(NULL); |
|
3816 CEikCba* cba(NULL); |
|
3817 CONST_CAST(CEikListBox*,this)->MopGetObject(bgc); |
|
3818 if ( bgc ) |
|
3819 { |
|
3820 cba = ( static_cast<CEikCba*>( bgc->ButtonGroup() ) ); // downcast from MEikButtonGroup |
|
3821 if ( cba ) |
|
3822 { |
|
3823 MSK = cba->Control(3); // MSK's position is 3 |
|
3824 } |
|
3825 } |
|
3826 TInt newResourceId(NULL); |
|
3827 if ( MSK && ( cba->ControlId( MSK ) == EAknSoftkeyMark ) && |
|
3828 View()->ItemIsSelected( CurrentItemIndex() ) ) |
|
3829 { |
|
3830 newResourceId = R_AVKON_SOFTKEY_UNMARK; |
|
3831 } |
|
3832 if ( MSK && ( cba->ControlId( MSK ) == EAknSoftkeyUnmark ) && |
|
3833 !View()->ItemIsSelected( CurrentItemIndex() ) ) |
|
3834 { |
|
3835 newResourceId = R_AVKON_SOFTKEY_MARK; |
|
3836 } |
|
3837 |
|
3838 if ( newResourceId ) |
|
3839 { |
|
3840 bgc->SetCommandL( 3,newResourceId ); |
|
3841 cba->DrawNow(); |
|
3842 } |
|
3843 _AKNTRACE_FUNC_EXIT; |
|
3844 } |
|
3845 |
|
3846 EXPORT_C void CEikListBox::UpdateScrollBarThumbs() const |
|
3847 { |
|
3848 _AKNTRACE_FUNC_ENTER; |
|
3849 if (!iSBFrame) |
|
3850 { |
|
3851 _AKNTRACE_FUNC_EXIT; |
|
3852 return; |
|
3853 } |
|
3854 TInt hThumbPos=iView->HScrollOffset(); |
|
3855 TInt vThumbPos=iView->CurrentItemIndex(); |
|
3856 |
|
3857 if ((iListBoxFlags & EPageAtOnceScrolling) || (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)) |
|
3858 { |
|
3859 TInt delta = iView->ItemHeight() + iView->ItemOffsetInPixels(); |
|
3860 vThumbPos = iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels(); |
|
3861 } |
|
3862 |
|
3863 iSBFrame->MoveHorizThumbTo(hThumbPos); |
|
3864 iSBFrame->MoveVertThumbTo(vThumbPos); |
|
3865 _AKNTRACE_FUNC_EXIT; |
|
3866 } |
|
3867 |
|
3868 EXPORT_C void CEikListBox::ReportListBoxEventL(MEikListBoxObserver::TListBoxEvent aEvent) |
|
3869 { |
|
3870 _AKNTRACE_FUNC_ENTER; |
|
3871 switch ( aEvent ) |
|
3872 { |
|
3873 case MEikListBoxObserver::EEventFlickStarted: |
|
3874 case MEikListBoxObserver::EEventPanningStarted: |
|
3875 { |
|
3876 iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee ); |
|
3877 if ( aEvent == MEikListBoxObserver::EEventFlickStarted ) |
|
3878 iListBoxExt->SetFlickOngoing( ETrue ); |
|
3879 else |
|
3880 iListBoxExt->SetPanningOngoing( ETrue ); |
|
3881 break; |
|
3882 } |
|
3883 |
|
3884 case MEikListBoxObserver::EEventFlickStopped: |
|
3885 case MEikListBoxObserver::EEventPanningStopped: |
|
3886 { |
|
3887 iItemDrawer->ClearFlags( CListItemDrawer::EDisableMarquee ); |
|
3888 if ( aEvent == MEikListBoxObserver::EEventFlickStopped ) |
|
3889 { |
|
3890 iListBoxExt->SetFlickOngoing( EFalse ); |
|
3891 } |
|
3892 else |
|
3893 { |
|
3894 iListBoxExt->SetPanningOngoing( EFalse ); |
|
3895 } |
|
3896 |
|
3897 break; |
|
3898 } |
|
3899 } |
|
3900 |
|
3901 if ( iListBoxObserver ) |
|
3902 { |
|
3903 TBool allowed = ETrue; |
|
3904 |
|
3905 if ( iListBoxExt && iListBoxExt->iPhysics |
|
3906 && aEvent != MEikListBoxObserver::EEventFlickStopped ) |
|
3907 { |
|
3908 allowed = iListBoxExt->iClickEventsAllowed; |
|
3909 } |
|
3910 |
|
3911 if ( allowed ) |
|
3912 { |
|
3913 iListBoxObserver->HandleListBoxEventL(this, aEvent); |
|
3914 } |
|
3915 } |
|
3916 _AKNTRACE_FUNC_EXIT; |
|
3917 } |
|
3918 |
|
3919 EXPORT_C TInt CEikListBox::HorizontalNudgeValue() const |
|
3920 { |
|
3921 return (iView->ViewRect().Width() / KEikListBoxHNudgeSizeAsFractionOfViewRectWidth); |
|
3922 } |
|
3923 |
|
3924 EXPORT_C CEikScrollBarFrame* const CEikListBox::ScrollBarFrame() |
|
3925 { |
|
3926 return iSBFrame; |
|
3927 } |
|
3928 |
|
3929 EXPORT_C void CEikListBox::SetScrollBarFrame(CEikScrollBarFrame* aScrollBarFrame, TScrollBarOwnerShip aOwnerShip) |
|
3930 { |
|
3931 if (iSBFrameOwned == ENotOwnedExternally) { delete iSBFrame; iSBFrame = 0; } |
|
3932 iSBFrame = aScrollBarFrame; |
|
3933 iSBFrameOwned = aOwnerShip; |
|
3934 } |
|
3935 |
|
3936 |
|
3937 // --------------------------------------------------------------------------- |
|
3938 // Scrolls the view by the given amount of pixels while keeping the |
|
3939 // physics parameters up-to-date. |
|
3940 // --------------------------------------------------------------------------- |
|
3941 // |
|
3942 EXPORT_C void CEikListBox::HandlePhysicsScrollEventL( TInt aDeltaPixels ) |
|
3943 { |
|
3944 _AKNTRACE_FUNC_ENTER; |
|
3945 if ( iListBoxExt->iPhysics ) |
|
3946 { |
|
3947 iListBoxExt->InitPhysicsL(); |
|
3948 |
|
3949 TPoint newPosition( iListBoxExt->iViewPosition.iX, |
|
3950 aDeltaPixels + iListBoxExt->iViewPosition.iY ); |
|
3951 iListBoxExt->ViewPositionChanged( newPosition ); |
|
3952 } |
|
3953 _AKNTRACE_FUNC_EXIT; |
|
3954 } |
|
3955 |
|
3956 |
|
3957 EXPORT_C void CEikListBox::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType) |
|
3958 { |
|
3959 _AKNTRACE_FUNC_ENTER; |
|
3960 if ( iListBoxExt->iSingleClickEnabled ) |
|
3961 { |
|
3962 iListBoxExt->EnableHighlight( EFalse ); |
|
3963 iView->DrawItem( iView->CurrentItemIndex() ); |
|
3964 } |
|
3965 |
|
3966 // When the scrollbar is scrolling, marquee will be disabled |
|
3967 // temporarily for performance reason. And before leaving this function, |
|
3968 // this flag must be cleaned. |
|
3969 iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee ); |
|
3970 |
|
3971 TInt oldThumbPos = (aEventType & KEikScrollEventBarMask) ? iView->HScrollOffset() : iView->TopItemIndex(); |
|
3972 TInt newThumbPos = aScrollBar->ThumbPosition(); |
|
3973 |
|
3974 TInt pageSize = 0; |
|
3975 TInt maxThumbPos = 0; |
|
3976 |
|
3977 if ( aScrollBar->Model()->ScrollBarModelType() == |
|
3978 TEikScrollBarModel::EAknDoubleSpanScrollBarModel ) |
|
3979 { |
|
3980 const TAknDoubleSpanScrollBarModel* dblSpanModel = |
|
3981 static_cast<const TAknDoubleSpanScrollBarModel*>( |
|
3982 aScrollBar->Model() ); |
|
3983 pageSize = dblSpanModel->WindowSize(); |
|
3984 maxThumbPos = dblSpanModel->ScrollSpan() - |
|
3985 dblSpanModel->WindowSize(); |
|
3986 } |
|
3987 else |
|
3988 { |
|
3989 pageSize = aScrollBar->Model()->iThumbSpan; |
|
3990 maxThumbPos = aScrollBar->Model()->MaxThumbPos(); |
|
3991 } |
|
3992 |
|
3993 TBool update = ETrue; // for the case EEikScrollThumbRelease so that after it there is now update. |
|
3994 TInt newThumbPosBeforeCorrecting = newThumbPos; |
|
3995 |
|
3996 switch (aEventType & KEikScrollEventBarMask) |
|
3997 { |
|
3998 case KEikScrollEventFromHBar: |
|
3999 switch (aEventType) |
|
4000 { |
|
4001 case EEikScrollLeft: |
|
4002 newThumbPos -= HorizontalNudgeValue(); |
|
4003 break; |
|
4004 case EEikScrollRight: |
|
4005 newThumbPos += HorizontalNudgeValue(); |
|
4006 break; |
|
4007 case EEikScrollPageLeft: |
|
4008 newThumbPos -= pageSize; |
|
4009 break; |
|
4010 case EEikScrollPageRight: |
|
4011 newThumbPos += pageSize; |
|
4012 break; |
|
4013 case EEikScrollThumbDragHoriz: |
|
4014 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4015 SuspendEffects( ETrue ); |
|
4016 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4017 if(AknLayoutUtils::PenEnabled()) |
|
4018 { |
|
4019 break; |
|
4020 } |
|
4021 case EEikScrollThumbReleaseHoriz: |
|
4022 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4023 SuspendEffects( EFalse ); |
|
4024 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4025 // in the case of drag events, the scrollbar automatically updates its thumb pos... |
|
4026 if(AknLayoutUtils::PenEnabled()) |
|
4027 { |
|
4028 update = EFalse; |
|
4029 } |
|
4030 break; |
|
4031 default: |
|
4032 break; |
|
4033 } |
|
4034 newThumbPos = Max(0, Min(newThumbPos, maxThumbPos)); |
|
4035 iView->HScroll(newThumbPos - oldThumbPos); |
|
4036 if (aEventType != EEikScrollThumbDragHoriz) |
|
4037 aScrollBar->SetModelThumbPosition(iView->HScrollOffset()); |
|
4038 break; |
|
4039 |
|
4040 case KEikScrollEventFromVBar: |
|
4041 switch (aEventType) |
|
4042 { |
|
4043 case EEikScrollUp: |
|
4044 if ( oldThumbPos == 0 && (iListBoxFlags & ELoopScrolling)) |
|
4045 { |
|
4046 newThumbPos = maxThumbPos; |
|
4047 } |
|
4048 break; |
|
4049 |
|
4050 case EEikScrollDown: |
|
4051 if ( oldThumbPos == maxThumbPos && (iListBoxFlags & ELoopScrolling) ) |
|
4052 { |
|
4053 newThumbPos = 0; |
|
4054 } |
|
4055 break; |
|
4056 |
|
4057 case EEikScrollPageUp: |
|
4058 break; |
|
4059 |
|
4060 case EEikScrollPageDown: |
|
4061 break; |
|
4062 |
|
4063 case EEikScrollThumbDragVert: |
|
4064 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4065 SuspendEffects( ETrue ); |
|
4066 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4067 if(AknLayoutUtils::PenEnabled()) |
|
4068 { |
|
4069 break; |
|
4070 } |
|
4071 case EEikScrollThumbReleaseVert: |
|
4072 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4073 SuspendEffects( EFalse ); |
|
4074 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4075 // in the case of drag events, the scrollbar automatically updates its thumb pos... |
|
4076 if(AknLayoutUtils::PenEnabled()) |
|
4077 { |
|
4078 update = EFalse; |
|
4079 } |
|
4080 break; |
|
4081 |
|
4082 default: |
|
4083 break; |
|
4084 } |
|
4085 |
|
4086 newThumbPos = Max(0, Min(newThumbPos, maxThumbPos)); |
|
4087 |
|
4088 if ( (!AknLayoutUtils::PenEnabled()) || update ) |
|
4089 { |
|
4090 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4091 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( |
|
4092 iView->iGc ); |
|
4093 TBool effects = transApi && !transApi->EffectsDisabled(); |
|
4094 |
|
4095 if ( effects ) |
|
4096 { |
|
4097 transApi->SetMoveType( newThumbPos < oldThumbPos ? |
|
4098 MAknListBoxTfxInternal::EListScrollUp : |
|
4099 MAknListBoxTfxInternal::EListScrollDown ); |
|
4100 } |
|
4101 #endif |
|
4102 |
|
4103 if ( iListBoxExt->iPhysics ) |
|
4104 { |
|
4105 iListBoxExt->InitPhysicsL(); |
|
4106 TInt deltaPixels = newThumbPos; |
|
4107 |
|
4108 #ifdef _DEBUG |
|
4109 RDebug::Print( _L( "CListBox::HandleScrollEventL, deltaPixels = %d" ), deltaPixels ); |
|
4110 #endif // _DEBUG |
|
4111 |
|
4112 TPoint newPosition( iListBoxExt->iViewPosition.iX, deltaPixels + iView->ViewRect().Height() / 2 ); |
|
4113 iListBoxExt->ViewPositionChanged( newPosition ); |
|
4114 } |
|
4115 else |
|
4116 { |
|
4117 iView->VScrollTo(newThumbPos/iView->ItemHeight()); |
|
4118 } |
|
4119 |
|
4120 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4121 if ( effects ) |
|
4122 { |
|
4123 transApi->Draw( Rect() ); |
|
4124 } |
|
4125 #endif |
|
4126 if (aEventType != EEikScrollThumbDragVert) |
|
4127 { |
|
4128 aScrollBar->SetModelThumbPosition(iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels()); |
|
4129 } |
|
4130 } |
|
4131 |
|
4132 // If the event has changed thumb position, then update scroll bar |
|
4133 // unless physics is used. In that case thumb is updated via |
|
4134 // CEikListBox::ScrollView. |
|
4135 if ( AknLayoutUtils::PenEnabled() && newThumbPos != newThumbPosBeforeCorrecting && !iListBoxExt->iPhysics ) |
|
4136 { |
|
4137 UpdateScrollBarThumbs(); |
|
4138 } |
|
4139 } |
|
4140 iItemDrawer->ClearFlags(CListItemDrawer::EDisableMarquee); |
|
4141 _AKNTRACE_FUNC_EXIT; |
|
4142 } |
|
4143 |
|
4144 EXPORT_C void CEikListBox::HandleDragEventL(TPoint aPointerPos) |
|
4145 { |
|
4146 // return immediately if kinetic scrolling is enabled, this needs to be modified afterwards |
|
4147 _AKNTRACE_FUNC_ENTER; |
|
4148 if ( iListBoxExt && iListBoxExt->iPhysics ) |
|
4149 { |
|
4150 _AKNTRACE_FUNC_EXIT; |
|
4151 return; |
|
4152 } |
|
4153 |
|
4154 CheckCreateExtensionL(); |
|
4155 if (!(iListBoxFlags & ELeftDownInViewRect)) |
|
4156 { |
|
4157 _AKNTRACE_FUNC_EXIT; |
|
4158 return; |
|
4159 } |
|
4160 |
|
4161 TRect viewRect(iView->ViewRect()); |
|
4162 if( !AknLayoutUtils::PenEnabled() ) |
|
4163 { |
|
4164 // We do not want highlight to move when dragged left/rightside of lists |
|
4165 if ((aPointerPos.iX > viewRect.iBr.iX) || (aPointerPos.iX < viewRect.iTl.iX)) |
|
4166 { |
|
4167 aPointerPos.iX = viewRect.iTl.iX; |
|
4168 } |
|
4169 } |
|
4170 TInt itemIndex( 0 ); |
|
4171 TBool pointerIsOverAnItem = iView->XYPosToItemIndex(aPointerPos, itemIndex); |
|
4172 CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection; |
|
4173 TInt oldCurrentItemIndex = iView->CurrentItemIndex(); |
|
4174 TInt oldTopItemIndex = iView->TopItemIndex(); |
|
4175 TInt oldBottomItemIndex = iView->BottomItemIndex(); |
|
4176 TInt topItemIndex ( oldTopItemIndex ); |
|
4177 TInt bottomItemIndex( oldBottomItemIndex ); |
|
4178 TInt interval = iListBoxExt->iInterval; |
|
4179 TInt speed = 0; |
|
4180 const TInt KBrakeL1 = 5; |
|
4181 const TInt KBrakeL2 = 10; |
|
4182 TInt lastItem = iModel->NumberOfItems() - 1; |
|
4183 TInt yDistance = aPointerPos.iY - iListBoxExt->iLastPoint.iY; |
|
4184 if(pointerIsOverAnItem && (itemIndex == oldBottomItemIndex) && yDistance > 0 ) |
|
4185 { |
|
4186 speed = 1; |
|
4187 } |
|
4188 else if(pointerIsOverAnItem && (itemIndex == oldTopItemIndex) && yDistance < 0 ) |
|
4189 { |
|
4190 speed = -1; |
|
4191 } |
|
4192 else if( pointerIsOverAnItem && |
|
4193 oldTopItemIndex < itemIndex && |
|
4194 oldBottomItemIndex > itemIndex ) |
|
4195 { |
|
4196 // highlight the item |
|
4197 speed = 0; |
|
4198 } |
|
4199 else if (aPointerPos.iY < viewRect.iTl.iY) |
|
4200 { |
|
4201 speed = - Min((( viewRect.iTl.iY + ItemHeight()) - aPointerPos.iY ) |
|
4202 / ( ItemHeight() / 2 ) * iListBoxExt->iStepSpeed, |
|
4203 iListBoxExt->iMaxSpeed ); |
|
4204 if ( oldTopItemIndex <= KBrakeL1 ) |
|
4205 { |
|
4206 speed = -1; |
|
4207 } |
|
4208 else if ( oldTopItemIndex + speed < KBrakeL1) |
|
4209 { |
|
4210 speed = KBrakeL1 - oldTopItemIndex; |
|
4211 } |
|
4212 } |
|
4213 else if (aPointerPos.iY > viewRect.iBr.iY) |
|
4214 { |
|
4215 speed = Min(( aPointerPos.iY - ( viewRect.iBr.iY - ItemHeight())) |
|
4216 / (ItemHeight() / 2) * iListBoxExt->iStepSpeed, |
|
4217 iListBoxExt->iMaxSpeed ); |
|
4218 if ( oldBottomItemIndex >= iModel->NumberOfItems() - 1 - KBrakeL1 ) |
|
4219 { |
|
4220 speed = 1; |
|
4221 } |
|
4222 else if ( oldBottomItemIndex + speed > lastItem - KBrakeL1 ) |
|
4223 { |
|
4224 speed = lastItem - oldBottomItemIndex - KBrakeL1; |
|
4225 } |
|
4226 } |
|
4227 // Brake level 2 |
|
4228 if ( ( speed < 0 && oldTopItemIndex + speed < KBrakeL2 ) |
|
4229 || ( speed > 0 && oldBottomItemIndex + speed > lastItem - KBrakeL2 )) |
|
4230 { |
|
4231 interval *= 2; |
|
4232 } |
|
4233 |
|
4234 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4235 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( |
|
4236 iView->iGc ); |
|
4237 TBool effects = transApi && !transApi->EffectsDisabled(); |
|
4238 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4239 TBool edge = EFalse; |
|
4240 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4241 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4242 if ( !ItemExists( oldTopItemIndex + speed ) || |
|
4243 !ItemExists( oldBottomItemIndex + speed)) |
|
4244 { |
|
4245 speed = 0; |
|
4246 } |
|
4247 iListBoxExt->iSpeed = speed; |
|
4248 if ( speed != 0 ) |
|
4249 { |
|
4250 topItemIndex = oldTopItemIndex + speed; |
|
4251 |
|
4252 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4253 if ( !effects ) |
|
4254 { |
|
4255 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4256 iView->SetTopItemIndex( topItemIndex ); |
|
4257 UpdateScrollBarThumbs(); |
|
4258 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4259 } |
|
4260 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4261 if ( pointerIsOverAnItem ) |
|
4262 { |
|
4263 Window().RequestPointerRepeatEvent(interval, |
|
4264 viewRect ); |
|
4265 } |
|
4266 // Pointer outside of list |
|
4267 else |
|
4268 { |
|
4269 TRect screenRect(TPoint(-1000, -1000), TPoint(1000, 1000)); |
|
4270 TRect ignoreDragRect; |
|
4271 |
|
4272 if ( AknLayoutUtils::PenEnabled() && |
|
4273 ( (aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY) ) && |
|
4274 !( (aPointerPos.iX > viewRect.iBr.iX) || (aPointerPos.iX < viewRect.iTl.iX) ) ) |
|
4275 { |
|
4276 if (aPointerPos.iY < viewRect.iTl.iY) |
|
4277 { |
|
4278 ignoreDragRect.SetRect( screenRect.iTl, |
|
4279 TPoint(screenRect.iBr.iX, viewRect.iTl.iY )); |
|
4280 } |
|
4281 else |
|
4282 { |
|
4283 ignoreDragRect.SetRect( TPoint( screenRect.iTl.iX, viewRect.iBr.iY), |
|
4284 screenRect.iBr ); |
|
4285 } |
|
4286 } |
|
4287 else if ( !AknLayoutUtils::PenEnabled() && |
|
4288 ((aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY)) ) |
|
4289 { |
|
4290 if (aPointerPos.iY < viewRect.iTl.iY) |
|
4291 { |
|
4292 ignoreDragRect.SetRect( screenRect.iTl, |
|
4293 TPoint( screenRect.iBr.iX, viewRect.iTl.iY )); |
|
4294 } |
|
4295 else |
|
4296 { |
|
4297 ignoreDragRect.SetRect( TPoint( screenRect.iTl.iX, viewRect.iBr.iY), |
|
4298 screenRect.iBr); |
|
4299 } |
|
4300 } |
|
4301 Window().RequestPointerRepeatEvent( interval, |
|
4302 ignoreDragRect ); |
|
4303 } |
|
4304 |
|
4305 pointerIsOverAnItem = iView->XYPosToItemIndex(aPointerPos, itemIndex); |
|
4306 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4307 if ( effects ) |
|
4308 { |
|
4309 bottomItemIndex = topItemIndex + oldBottomItemIndex - oldTopItemIndex; |
|
4310 } |
|
4311 else |
|
4312 { |
|
4313 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4314 topItemIndex = iView->TopItemIndex(); |
|
4315 bottomItemIndex = iView->BottomItemIndex(); |
|
4316 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4317 } |
|
4318 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4319 // When scrolling don't focus first / last item unless it's really |
|
4320 // the first / last item of the list |
|
4321 if ( speed > 0 /*&& itemIndex == bottomItemIndex*/ ) |
|
4322 { |
|
4323 if ( ItemExists ( bottomItemIndex +1 ) ) |
|
4324 { |
|
4325 itemIndex = bottomItemIndex - 1; |
|
4326 } |
|
4327 else |
|
4328 { |
|
4329 itemIndex = bottomItemIndex; |
|
4330 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4331 edge = ETrue; |
|
4332 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4333 } |
|
4334 } |
|
4335 if ( speed < 0 /*&& itemIndex == topItemIndex*/ ) |
|
4336 { |
|
4337 if ( ItemExists ( topItemIndex -1 ) ) |
|
4338 { |
|
4339 itemIndex = topItemIndex + 1; |
|
4340 } |
|
4341 else |
|
4342 { |
|
4343 itemIndex = topItemIndex; |
|
4344 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4345 edge = ETrue; |
|
4346 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4347 } |
|
4348 } |
|
4349 |
|
4350 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4351 if ( speed != 0 && !effects ) |
|
4352 #else |
|
4353 if(speed != 0) |
|
4354 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4355 { |
|
4356 SetCurrentItemIndex(itemIndex); |
|
4357 DrawNow(); |
|
4358 } |
|
4359 |
|
4360 } |
|
4361 |
|
4362 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4363 if ( effects ) |
|
4364 { |
|
4365 if ( AknLayoutUtils::PenEnabled() && |
|
4366 ( iListBoxFlags & ES60StyleMultiselection || |
|
4367 ((iListBoxFlags & ES60StyleMarkable) && |
|
4368 ( (iListBoxExt->iEventModifiers & EModifierShift) || |
|
4369 (iListBoxExt->iEventModifiers & EModifierCtrl) )))) |
|
4370 { |
|
4371 if ( speed == 0 ) |
|
4372 { |
|
4373 if ( itemIndex == oldCurrentItemIndex ) |
|
4374 { |
|
4375 _AKNTRACE_FUNC_EXIT; |
|
4376 return; |
|
4377 } |
|
4378 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag ); |
|
4379 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified, |
|
4380 viewRect ); |
|
4381 iView->SetTopItemIndex( topItemIndex ); |
|
4382 iView->SetItemIndex( itemIndex ); |
|
4383 UpdateSelectionsL( iView, transApi, itemIndex, oldCurrentItemIndex, iListBoxExt->iAnchor, iListBoxExt->iSelect ); |
|
4384 } |
|
4385 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4386 else if ( edge ) |
|
4387 { |
|
4388 transApi->SetMoveType( MAknListBoxTfxInternal::EListHitBorder ); |
|
4389 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified, |
|
4390 viewRect ); |
|
4391 iView->SetTopItemIndex( topItemIndex ); |
|
4392 iView->SetItemIndex( itemIndex ); |
|
4393 UpdateSelectionsL( iView, transApi, itemIndex, oldCurrentItemIndex, iListBoxExt->iAnchor, iListBoxExt->iSelect ); |
|
4394 } |
|
4395 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4396 else |
|
4397 { |
|
4398 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag ); |
|
4399 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified, |
|
4400 viewRect ); |
|
4401 iView->SetTopItemIndex( topItemIndex ); |
|
4402 iView->SetItemIndex( itemIndex ); |
|
4403 UpdateSelectionsL( iView, transApi, itemIndex, oldCurrentItemIndex, iListBoxExt->iAnchor, iListBoxExt->iSelect ); |
|
4404 } |
|
4405 } |
|
4406 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4407 else if ( edge || iListBoxExt->iSpeed == 0 ) |
|
4408 #else |
|
4409 else if ( iListBoxExt->iSpeed == 0 ) |
|
4410 #endif |
|
4411 { |
|
4412 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4413 if ( iListBoxExt->iSpeed == 0 ) |
|
4414 { |
|
4415 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4416 if ( itemIndex == oldCurrentItemIndex || itemIndex < 0 ) |
|
4417 { |
|
4418 // If itemIndex didn't change or itemIndex doesn't |
|
4419 // exist, just return |
|
4420 _AKNTRACE_FUNC_EXIT; |
|
4421 return; |
|
4422 } |
|
4423 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag ); |
|
4424 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4425 } |
|
4426 else |
|
4427 { |
|
4428 transApi->SetMoveType( MAknListBoxTfxInternal::EListHitBorder ); |
|
4429 } |
|
4430 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2 |
|
4431 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified, |
|
4432 viewRect ); |
|
4433 iView->SetTopItemIndex( topItemIndex ); |
|
4434 iView->SetItemIndex( itemIndex ); |
|
4435 iView->DrawItem( itemIndex ); |
|
4436 iView->DrawItem( oldCurrentItemIndex ); |
|
4437 for ( TInt i = iView->TopItemIndex(); i <= iView->BottomItemIndex(); i++ ) |
|
4438 { |
|
4439 if ( i != itemIndex && i != oldCurrentItemIndex && |
|
4440 transApi->SetPosition( MAknListBoxTfxInternal::EListItem, iView->ItemPos( i ), i ) != KErrNone ) |
|
4441 { |
|
4442 iView->DrawItem( i ); |
|
4443 } |
|
4444 } |
|
4445 } |
|
4446 else |
|
4447 { |
|
4448 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag ); |
|
4449 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified, |
|
4450 viewRect ); |
|
4451 iView->SetItemIndex( itemIndex ); |
|
4452 iView->DrawItem( oldCurrentItemIndex ); |
|
4453 iView->SetTopItemIndex( topItemIndex ); |
|
4454 transApi->SetPosition( MAknListBoxTfxInternal::EListHighlight, iView->ItemPos( itemIndex ) ); |
|
4455 for ( TInt i = iView->TopItemIndex(); i <= iView->BottomItemIndex(); i++ ) |
|
4456 { |
|
4457 iView->DrawItem( i ); |
|
4458 } |
|
4459 } |
|
4460 transApi->SetPosition( MAknListBoxTfxInternal::EListHighlight, iView->ItemPos( itemIndex ) ); |
|
4461 UpdateScrollBarThumbs(); |
|
4462 if ( AknLayoutUtils::PenEnabled() ) |
|
4463 { |
|
4464 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
4465 // drag feedback, also for viewers |
|
4466 TBool feedbackNeeded = !(iListBoxFlags & EPageAtOnceScrolling) // editor case |
|
4467 || (oldTopItemIndex != topItemIndex || oldBottomItemIndex != bottomItemIndex); // viewer case |
|
4468 if ( feedback && feedbackNeeded ) |
|
4469 { |
|
4470 feedback->InstantFeedback( ETouchFeedbackSensitive ); |
|
4471 } |
|
4472 ReportListBoxEventL( MEikListBoxObserver::EEventItemDraggingActioned ); |
|
4473 } |
|
4474 |
|
4475 transApi->EndRedraw( MAknListBoxTfxInternal::EListNotSpecified ); |
|
4476 _AKNTRACE_FUNC_EXIT; |
|
4477 return; |
|
4478 } |
|
4479 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4480 |
|
4481 if (pointerIsOverAnItem) |
|
4482 { |
|
4483 // drag event occurred within the listbox |
|
4484 if ( itemIndex == oldCurrentItemIndex ) |
|
4485 { |
|
4486 _AKNTRACE_FUNC_EXIT; |
|
4487 return; |
|
4488 } |
|
4489 if ( AknLayoutUtils::PenEnabled() && |
|
4490 ( iListBoxFlags & ES60StyleMultiselection || |
|
4491 ((iListBoxFlags & ES60StyleMarkable) && |
|
4492 ( (iListBoxExt->iEventModifiers & EModifierShift) || |
|
4493 (iListBoxExt->iEventModifiers & EModifierCtrl) )))) |
|
4494 { |
|
4495 iView->VerticalMoveToItemL( itemIndex, CListBoxView::EPenMultiselection ); |
|
4496 iListBoxFlags |= EStateChanged; |
|
4497 } |
|
4498 else |
|
4499 { |
|
4500 iView->VerticalMoveToItemL( itemIndex, selectionMode ); |
|
4501 UpdateMarkUnmarkMSKL(); |
|
4502 } |
|
4503 UpdateScrollBarThumbs(); |
|
4504 } |
|
4505 else if (viewRect.Contains(aPointerPos)) |
|
4506 { |
|
4507 // find item nearest to the pointer pos and make that the current item |
|
4508 if( iListBoxExt->iIsDownOnItem ) |
|
4509 { |
|
4510 if( yDistance>0 && itemIndex != oldBottomItemIndex ) |
|
4511 { |
|
4512 iView->SetCurrentItemIndex( oldBottomItemIndex ); |
|
4513 } |
|
4514 else if( yDistance<0 && itemIndex != oldTopItemIndex ) |
|
4515 { |
|
4516 iView->SetCurrentItemIndex( oldTopItemIndex ); |
|
4517 } |
|
4518 DrawDeferred(); |
|
4519 } |
|
4520 } |
|
4521 else if ( AknLayoutUtils::PenEnabled() && |
|
4522 ( (aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY) ) && |
|
4523 !( (aPointerPos.iX > viewRect.iBr.iX) || (aPointerPos.iX < viewRect.iTl.iX) ) && |
|
4524 // Scroll when stulying donw on item other than empty area. |
|
4525 iListBoxExt->iIsDownOnItem ) |
|
4526 { |
|
4527 // drag event occurred outside the listbox's viewRect |
|
4528 |
|
4529 if ( iListBoxFlags & ES60StyleMultiselection || |
|
4530 ((iListBoxFlags & ES60StyleMarkable) && |
|
4531 ( (iListBoxExt->iEventModifiers & EModifierShift) || |
|
4532 (iListBoxExt->iEventModifiers & EModifierCtrl) ))) |
|
4533 { |
|
4534 iView->SetCurrentItemIndex(itemIndex); |
|
4535 iView->UpdateSelectionL(CListBoxView::EPenMultiselection); |
|
4536 iListBoxFlags |= EStateChanged; |
|
4537 } |
|
4538 } |
|
4539 else if ( !AknLayoutUtils::PenEnabled() && |
|
4540 ((aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY)) ) |
|
4541 { |
|
4542 // drag event occurred outside the listbox's viewRect |
|
4543 TRect screenRect(TPoint(-1000, -1000), TPoint(1000, 1000)); |
|
4544 TRect ignoreDragRect; |
|
4545 TInt oldTopItemIndex = iView->TopItemIndex(); |
|
4546 TInt oldBottomItemIndex = iView->BottomItemIndex(); |
|
4547 if (aPointerPos.iY < viewRect.iTl.iY) |
|
4548 { |
|
4549 ignoreDragRect.SetRect(screenRect.iTl, TPoint(screenRect.iBr.iX, viewRect.iTl.iY)); |
|
4550 itemIndex = ItemExists(oldTopItemIndex-1) ? (oldTopItemIndex-1) : oldTopItemIndex; |
|
4551 } |
|
4552 else |
|
4553 { |
|
4554 ignoreDragRect.SetRect(TPoint(screenRect.iTl.iX, viewRect.iBr.iY), screenRect.iBr); |
|
4555 itemIndex = ItemExists(oldBottomItemIndex+1) ? (oldBottomItemIndex+1) : oldBottomItemIndex; |
|
4556 } |
|
4557 |
|
4558 SetCurrentItemIndexAndDraw(itemIndex); |
|
4559 UpdateScrollBarThumbs(); |
|
4560 Window().RequestPointerRepeatEvent( interval, ignoreDragRect); |
|
4561 } |
|
4562 |
|
4563 if (itemIndex != oldCurrentItemIndex) |
|
4564 { |
|
4565 iView->UpdateSelectionL(selectionMode); |
|
4566 |
|
4567 if(AknLayoutUtils::PenEnabled()) |
|
4568 { |
|
4569 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
4570 // drag feedback, also for viewers |
|
4571 TBool feedbackNeeded = !(iListBoxFlags & EPageAtOnceScrolling) // editor case |
|
4572 || (oldTopItemIndex != topItemIndex || oldBottomItemIndex != bottomItemIndex); // viewer case |
|
4573 if ( feedback && feedbackNeeded ) |
|
4574 { |
|
4575 feedback->InstantFeedback( ETouchFeedbackSensitive ); |
|
4576 } |
|
4577 |
|
4578 ReportListBoxEventL(MEikListBoxObserver::EEventItemDraggingActioned); |
|
4579 } |
|
4580 |
|
4581 iListBoxFlags |= EStateChanged; |
|
4582 if (IsMatchBuffer()) |
|
4583 { |
|
4584 ClearMatchBuffer(); |
|
4585 DrawMatcherCursor(); |
|
4586 } |
|
4587 } |
|
4588 _AKNTRACE_FUNC_EXIT; |
|
4589 } |
|
4590 |
|
4591 // The function EnableRedraw was declared but never put to use. |
|
4592 //LOCAL_C void EnableRedraw(TAny* aPtr) |
|
4593 // { |
|
4594 // CListBoxView& lbv=*(CListBoxView*)aPtr; |
|
4595 // lbv.SetDisableRedraw(EFalse); |
|
4596 // } |
|
4597 |
|
4598 EXPORT_C void* CEikListBox::ExtensionInterface( TUid /*aInterface*/ ) |
|
4599 { |
|
4600 return NULL; |
|
4601 } |
|
4602 |
|
4603 EXPORT_C void CEikListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
4604 { |
|
4605 _AKNTRACE_FUNC_ENTER; |
|
4606 |
|
4607 CheckCreateBufferL(); // don't need to create the full matching buffer here - only the iPressedIndex |
|
4608 TInt itemIndex( KErrNotFound ); |
|
4609 TPoint pointerPos(aPointerEvent.iPosition); |
|
4610 TBool pointerIsOverAnItem = iView->XYPosToItemIndex(pointerPos, itemIndex); |
|
4611 TInt oldCurrentItemIndex; |
|
4612 TBool listEmpty = !ItemExists( iView->TopItemIndex() ); |
|
4613 |
|
4614 // Handle empty list area events |
|
4615 if ( aPointerEvent.iType == TPointerEvent::EButton1Up && |
|
4616 !iListBoxExt->iScrolling && !iListBoxExt->iIsDownOnItem ) |
|
4617 { |
|
4618 if ( listEmpty ) |
|
4619 { |
|
4620 // No items, empty list was clicked |
|
4621 ReportListBoxEventL( MEikListBoxObserver::EEventEmptyListClicked ); |
|
4622 _AKNTRACE_FUNC_EXIT; |
|
4623 return; |
|
4624 } |
|
4625 else if ( !pointerIsOverAnItem ) |
|
4626 { |
|
4627 // Items exist, empty list area was clicked |
|
4628 ReportListBoxEventL( MEikListBoxObserver::EEventEmptyAreaClicked ); |
|
4629 _AKNTRACE_FUNC_EXIT; |
|
4630 return; |
|
4631 } |
|
4632 } |
|
4633 else if ( listEmpty ) |
|
4634 { |
|
4635 // Return always if list empty to avoid tactile feedback |
|
4636 _AKNTRACE_FUNC_EXIT; |
|
4637 return; |
|
4638 } |
|
4639 |
|
4640 |
|
4641 // When in marking mode, pointer events should not be forwarded to |
|
4642 // long tap detector, this boolean indicates if marking mode is active |
|
4643 TBool markingMode( iListBoxExt->MarkedItems() ); |
|
4644 |
|
4645 if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) |
|
4646 { |
|
4647 if ( iListBoxExt->iSingleClickEnabled && |
|
4648 itemIndex != iView->CurrentItemIndex() ) |
|
4649 { |
|
4650 iListBoxExt->EnableHighlight( EFalse ); |
|
4651 iView->DrawItem( iView->CurrentItemIndex() ); |
|
4652 } |
|
4653 |
|
4654 iListBoxExt->iFeedbackType = ETouchFeedbackList; |
|
4655 |
|
4656 if ( itemIndex != iView->CurrentItemIndex() || |
|
4657 iListBoxFlags & ES60StyleMultiselection ) |
|
4658 { |
|
4659 iListBoxExt->iFeedbackType = ETouchFeedbackSensitiveList; |
|
4660 } |
|
4661 |
|
4662 if ( iListBoxExt->iPhysics && |
|
4663 iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionFlicking ) |
|
4664 { |
|
4665 iListBoxExt->iFeedbackType = ETouchFeedbackList; |
|
4666 } |
|
4667 |
|
4668 if ( !iListBoxExt->iPhysics || itemIndex == iView->CurrentItemIndex() ) |
|
4669 { |
|
4670 iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType, |
|
4671 TTouchFeedbackType(ETouchFeedbackVibra | ETouchFeedbackAudio), |
|
4672 aPointerEvent ); |
|
4673 } |
|
4674 } |
|
4675 iListBoxExt->iEventModifiers = aPointerEvent.iModifiers; |
|
4676 CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection; |
|
4677 TBool shiftKeyPressed = EFalse; |
|
4678 TBool controlKeyPressed = EFalse; |
|
4679 |
|
4680 if (iListBoxFlags & EMultipleSelection) |
|
4681 { |
|
4682 // determine selection mode |
|
4683 if ( iListBoxExt->iShiftKeyPressed ) |
|
4684 { |
|
4685 shiftKeyPressed = ETrue; |
|
4686 } |
|
4687 else |
|
4688 { |
|
4689 shiftKeyPressed = (aPointerEvent.iModifiers) & EModifierShift; |
|
4690 } |
|
4691 controlKeyPressed = (aPointerEvent.iModifiers) & EModifierCtrl; |
|
4692 if (shiftKeyPressed) |
|
4693 selectionMode = CListBoxView::EContiguousSelection; |
|
4694 else if (controlKeyPressed) |
|
4695 selectionMode = CListBoxView::EDisjointSelection; |
|
4696 } |
|
4697 |
|
4698 TBool s60StyleMultiselection = EFalse; |
|
4699 TBool s60StyleMarkable = EFalse; |
|
4700 |
|
4701 if (iListBoxFlags & ENoExtendedSelection) |
|
4702 { |
|
4703 controlKeyPressed = ETrue; |
|
4704 selectionMode = CListBoxView::EDisjointSelection; |
|
4705 } |
|
4706 |
|
4707 if (iListBoxFlags & ES60StyleMultiselection ) |
|
4708 { |
|
4709 s60StyleMultiselection = ETrue; |
|
4710 selectionMode = CListBoxView::EDisjointSelection; |
|
4711 } |
|
4712 else if (iListBoxFlags & ES60StyleMarkable ) |
|
4713 { |
|
4714 s60StyleMarkable = ETrue; |
|
4715 } |
|
4716 |
|
4717 if ( (aPointerEvent.iModifiers&EModifierDoubleClick) |
|
4718 && pointerIsOverAnItem && selectionMode == CListBoxView::ENoSelection |
|
4719 && ( !iListBoxExt->IsInHandleAllPointEventArray( itemIndex ) )) |
|
4720 { |
|
4721 // Do not return here if S60StyleMultiselection is used |
|
4722 if ( !(iListBoxFlags & ES60StyleMultiselection) && |
|
4723 !(iListBoxFlags & ES60StyleMarkable) ) |
|
4724 { |
|
4725 iListBoxExt->iEventModifiers = 0; |
|
4726 } |
|
4727 |
|
4728 if(Buffer()->iPressedIndex == itemIndex) |
|
4729 { |
|
4730 Buffer()->iPressedIndex = KEikListBoxInvalidIndex; |
|
4731 _AKNTRACE_FUNC_EXIT; |
|
4732 return; |
|
4733 } |
|
4734 } |
|
4735 |
|
4736 TBool simulateOkKey = EFalse; |
|
4737 |
|
4738 TBool hasPhysics = ( iListBoxExt && iListBoxExt->iPhysics ); |
|
4739 TBool wasFlicking = EFalse; |
|
4740 |
|
4741 if ( hasPhysics ) |
|
4742 { |
|
4743 if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) |
|
4744 { |
|
4745 wasFlicking = ( iListBoxExt->iPhysics |
|
4746 && iListBoxExt->iPhysics->OngoingPhysicsAction() == |
|
4747 CAknPhysics::EAknPhysicsActionFlicking ); |
|
4748 } |
|
4749 if ( HandlePhysicsPointerEventL( aPointerEvent ) ) |
|
4750 { |
|
4751 _AKNTRACE_FUNC_EXIT; |
|
4752 return; |
|
4753 } |
|
4754 } |
|
4755 |
|
4756 switch (aPointerEvent.iType) |
|
4757 { |
|
4758 case TPointerEvent::EButton1Down: |
|
4759 _AKNTRACE("TPointerEvent::EButton1Down"); |
|
4760 // For drag outside listbox |
|
4761 iListBoxExt->iIsDownOnItem = pointerIsOverAnItem; |
|
4762 iListBoxExt->iLastPoint = pointerPos; |
|
4763 |
|
4764 // update index of the last down tapped item |
|
4765 iListBoxExt->iLastDownTappedItem = itemIndex; |
|
4766 |
|
4767 if ((! (Rect().Contains(aPointerEvent.iPosition))) && (iListBoxFlags & EPopout)) |
|
4768 { |
|
4769 ReportEventL(MCoeControlObserver::EEventRequestCancel); |
|
4770 iListBoxExt->iEventModifiers = 0; |
|
4771 _AKNTRACE_FUNC_EXIT; |
|
4772 return; |
|
4773 } |
|
4774 if (iView->ViewRect().Contains(aPointerEvent.iPosition)) |
|
4775 iListBoxFlags|=ELeftDownInViewRect; |
|
4776 else |
|
4777 { |
|
4778 iListBoxExt->iEventModifiers = 0; |
|
4779 _AKNTRACE_FUNC_EXIT; |
|
4780 return; |
|
4781 } |
|
4782 |
|
4783 oldCurrentItemIndex = iView->CurrentItemIndex(); |
|
4784 Buffer()->iDragToAnotherItem = EFalse; |
|
4785 if (pointerIsOverAnItem) |
|
4786 { |
|
4787 // check if pressed in the same position, if not reset pressed |
|
4788 Buffer()->iPressedIndex = (itemIndex==oldCurrentItemIndex ? itemIndex : KEikListBoxInvalidIndex); |
|
4789 |
|
4790 if ( !hasPhysics && !iListBoxExt->iSingleClickEnabled ) |
|
4791 { |
|
4792 iItemDrawer->ClearFlags ( CListItemDrawer::EDisableHighlight ); |
|
4793 } |
|
4794 |
|
4795 if ( !hasPhysics || !iListBoxExt->HighlightTimerActive() ) |
|
4796 { |
|
4797 // If single click mode is enabled and no physics enabled, |
|
4798 // set highlight visible on pointer down. |
|
4799 if ( iListBoxExt->iSingleClickEnabled ) |
|
4800 { |
|
4801 // If flick was stopped - give only tactile feedback |
|
4802 if ( !wasFlicking ) |
|
4803 { |
|
4804 iListBoxExt->EnableHighlight( ETrue, ETrue ); |
|
4805 UpdateHighlightL( itemIndex ); |
|
4806 CCoeEnv::Static()->WsSession().Finish(); |
|
4807 } |
|
4808 if ( itemIndex != oldCurrentItemIndex ) |
|
4809 { |
|
4810 iListBoxExt->ImmediateFeedback( |
|
4811 iListBoxExt->iFeedbackType, |
|
4812 TTouchFeedbackType( ETouchFeedbackVibra | |
|
4813 ETouchFeedbackAudio ), |
|
4814 aPointerEvent ); |
|
4815 } |
|
4816 if ( !wasFlicking ) |
|
4817 { |
|
4818 ReportListBoxEventL( |
|
4819 MEikListBoxObserver::EEventPenDownOnItem ); |
|
4820 iListBoxExt->LongTapPointerEventL( aPointerEvent ); |
|
4821 } |
|
4822 } |
|
4823 else |
|
4824 { |
|
4825 ReportListBoxEventL( |
|
4826 MEikListBoxObserver::EEventPenDownOnItem ); |
|
4827 } |
|
4828 } |
|
4829 else |
|
4830 { |
|
4831 iListBoxExt->iReportDelayedPenDown = ETrue; |
|
4832 iListBoxExt->iDelayedPointerDownEvent = aPointerEvent; |
|
4833 } |
|
4834 |
|
4835 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4836 if ( itemIndex != oldCurrentItemIndex ) |
|
4837 { |
|
4838 MAknListBoxTfxInternal* transApi = |
|
4839 CAknListLoader::TfxApiInternal( iView->iGc ); |
|
4840 if ( transApi && !transApi->EffectsDisabled() ) |
|
4841 { |
|
4842 transApi->SetMoveType( MAknListBoxTfxInternal::EListTap ); |
|
4843 } |
|
4844 } |
|
4845 #endif |
|
4846 if (!(iListBoxFlags & EMultipleSelection)) // i.e. this is a single selection listbox |
|
4847 { |
|
4848 if (itemIndex == oldCurrentItemIndex) |
|
4849 { |
|
4850 iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); |
|
4851 iView->DrawItem( itemIndex ); |
|
4852 |
|
4853 iListBoxExt->iEventModifiers = 0; |
|
4854 _AKNTRACE_FUNC_EXIT; |
|
4855 return; |
|
4856 } |
|
4857 |
|
4858 if ( !hasPhysics ) |
|
4859 { |
|
4860 iView->SetItemIndex(itemIndex); |
|
4861 iView->DrawItem(oldCurrentItemIndex); |
|
4862 iView->DrawItem(itemIndex); |
|
4863 } |
|
4864 |
|
4865 iListBoxFlags |= EStateChanged; |
|
4866 } |
|
4867 else if ( s60StyleMultiselection ) |
|
4868 { |
|
4869 if ( !hasPhysics || !iListBoxExt->HighlightTimerActive() ) |
|
4870 { |
|
4871 iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); |
|
4872 |
|
4873 iView->SetItemIndex(itemIndex); |
|
4874 iView->DrawItem(oldCurrentItemIndex); |
|
4875 iView->DrawItem(itemIndex); |
|
4876 iListBoxFlags |= EStateChanged; |
|
4877 Buffer()->iPressedIndex = itemIndex; |
|
4878 |
|
4879 if ( !hasPhysics ) |
|
4880 { |
|
4881 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
4882 } |
|
4883 |
|
4884 ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked); |
|
4885 } |
|
4886 else |
|
4887 { |
|
4888 iListBoxExt->iDelayedMultiselection = ETrue; |
|
4889 } |
|
4890 } |
|
4891 else if ( s60StyleMarkable ) |
|
4892 { |
|
4893 if ( !hasPhysics ) |
|
4894 { |
|
4895 iView->SetItemIndex( itemIndex ); |
|
4896 } |
|
4897 else |
|
4898 { // shift key will be handled in highlight timer |
|
4899 iListBoxExt->iMarkableListMarking = ETrue; |
|
4900 if ( shiftKeyPressed ) |
|
4901 { |
|
4902 iListBoxExt->iMarkableListShiftKeyPressed = ETrue; |
|
4903 // EPenMultiSelection moved to timer callback |
|
4904 // CListBoxView::EPenMultiselection; |
|
4905 selectionMode = CListBoxView::ENoSelection; |
|
4906 } |
|
4907 else |
|
4908 { |
|
4909 iListBoxExt->iMarkableListShiftKeyPressed = EFalse; |
|
4910 } |
|
4911 } |
|
4912 |
|
4913 if ( itemIndex == oldCurrentItemIndex ) |
|
4914 { |
|
4915 if ( shiftKeyPressed ) |
|
4916 { |
|
4917 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4918 iListBoxExt->iAnchor = oldCurrentItemIndex; |
|
4919 iListBoxExt->iSelect = |
|
4920 !iView->ItemIsSelected( iView->CurrentItemIndex() ); |
|
4921 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4922 |
|
4923 iView->SetAnchor( oldCurrentItemIndex ); |
|
4924 iView->UpdateSelectionL( CListBoxView::EChangeMarkMode ); |
|
4925 selectionMode = CListBoxView::EPenMultiselection; |
|
4926 iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); |
|
4927 } |
|
4928 else |
|
4929 { |
|
4930 iView->SetAnchor( itemIndex - 1 ); |
|
4931 |
|
4932 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
4933 iListBoxExt->iAnchor = itemIndex - 1; |
|
4934 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
4935 } |
|
4936 } |
|
4937 |
|
4938 if ( !hasPhysics ) |
|
4939 { |
|
4940 iView->DrawItem( oldCurrentItemIndex ); |
|
4941 } |
|
4942 |
|
4943 iView->UpdateSelectionL( selectionMode ); |
|
4944 iListBoxFlags |= EStateChanged; |
|
4945 |
|
4946 if ( !hasPhysics ) |
|
4947 { |
|
4948 iView->DrawItem( itemIndex ); |
|
4949 } |
|
4950 } |
|
4951 else // multiple selection listbox |
|
4952 { |
|
4953 if ((itemIndex == oldCurrentItemIndex) && (iView->ItemIsSelected(itemIndex)) && (! controlKeyPressed)) |
|
4954 { |
|
4955 iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); |
|
4956 iView->DrawItem( itemIndex ); |
|
4957 iListBoxExt->iEventModifiers = 0; |
|
4958 _AKNTRACE_FUNC_EXIT; |
|
4959 return; |
|
4960 } |
|
4961 |
|
4962 if ( !hasPhysics ) |
|
4963 { |
|
4964 iView->SetItemIndex(itemIndex); |
|
4965 iView->DrawItem(oldCurrentItemIndex); |
|
4966 } |
|
4967 |
|
4968 iView->UpdateSelectionL(selectionMode); |
|
4969 iListBoxFlags |= EStateChanged; |
|
4970 } |
|
4971 if (itemIndex != oldCurrentItemIndex) |
|
4972 { |
|
4973 iListBoxFlags |= EStateChanged; |
|
4974 // Fixed for TSW error ETLN-7T2CSR. |
|
4975 if ( !hasPhysics && IsMatchBuffer() ) |
|
4976 { |
|
4977 ClearMatchBuffer(); |
|
4978 DrawMatcherCursor(); |
|
4979 } |
|
4980 } |
|
4981 else |
|
4982 { |
|
4983 iItemDrawer->SetFlags( |
|
4984 CListItemDrawer::EPressedDownState ); |
|
4985 iView->DrawItem( itemIndex ); |
|
4986 } |
|
4987 } |
|
4988 break; |
|
4989 |
|
4990 case TPointerEvent::EButton1Up: |
|
4991 _AKNTRACE("TPointerEvent::EButton1Up"); |
|
4992 if ( iListBoxExt->FeedbackEnabledOnUpEvent() && iListBoxExt->iClickEventsAllowed ) |
|
4993 { |
|
4994 TTouchLogicalFeedback fbType = ETouchFeedbackList; |
|
4995 if ( iListBoxFlags & ES60StyleMultiselection ) |
|
4996 { |
|
4997 fbType = ETouchFeedbackCheckbox; |
|
4998 } |
|
4999 iListBoxExt->ImmediateFeedback( fbType, |
|
5000 ETouchFeedbackVibra, |
|
5001 aPointerEvent ); |
|
5002 } |
|
5003 if ((! (Rect().Contains(aPointerEvent.iPosition))) && (iListBoxFlags & EPopout)) |
|
5004 { |
|
5005 ReportEventL(MCoeControlObserver::EEventRequestCancel); |
|
5006 iListBoxExt->iEventModifiers = 0; |
|
5007 _AKNTRACE_FUNC_EXIT; |
|
5008 return; |
|
5009 } |
|
5010 if (!(iListBoxFlags & ELeftDownInViewRect)) |
|
5011 { |
|
5012 iListBoxExt->iEventModifiers = 0; |
|
5013 _AKNTRACE_FUNC_EXIT; |
|
5014 return; |
|
5015 } |
|
5016 |
|
5017 if (iListBoxFlags & EStateChanged) |
|
5018 { |
|
5019 iListBoxFlags &= (~EStateChanged); |
|
5020 if ( !s60StyleMultiselection ) |
|
5021 { |
|
5022 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
5023 UpdateMarkUnmarkMSKL(); |
|
5024 } |
|
5025 } |
|
5026 iListBoxFlags&=(~ELeftDownInViewRect); |
|
5027 if (pointerIsOverAnItem) |
|
5028 { |
|
5029 TUint32 lastPointUpTime = iListBoxExt->iListPointUpTime; |
|
5030 iListBoxExt->iListPointUpTime = User::NTickCount(); |
|
5031 |
|
5032 TInt lastItemIndex = iListBoxExt->iLastItemIndex; |
|
5033 iListBoxExt->iLastItemIndex = itemIndex; |
|
5034 |
|
5035 if ( ( iListBoxExt->iListPointUpTime - lastPointUpTime < KTwoPointerUpEventInterval ) |
|
5036 && lastItemIndex == itemIndex |
|
5037 && ( !iListBoxExt->IsInHandleAllPointEventArray( itemIndex ) ) |
|
5038 && !hasPhysics ) |
|
5039 { |
|
5040 iListBoxExt->iLastItemIndex = KEikListBoxInvalidIndex; |
|
5041 _AKNTRACE_FUNC_EXIT; |
|
5042 return; |
|
5043 } |
|
5044 |
|
5045 if ( !hasPhysics ) |
|
5046 { |
|
5047 iListBoxExt->LongTapPointerEventL( aPointerEvent ); |
|
5048 } |
|
5049 if ( !s60StyleMultiselection ) |
|
5050 { |
|
5051 if ( !iListBoxExt->iSingleClickEnabled ) |
|
5052 { |
|
5053 ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked); |
|
5054 } |
|
5055 else if ( itemIndex == iListBoxExt->iLastDownTappedItem ) |
|
5056 { |
|
5057 // Single click item activation |
|
5058 iListBoxExt->EnableHighlight( EFalse ); |
|
5059 UpdateHighlightL( itemIndex ); |
|
5060 ReportListBoxEventL( |
|
5061 MEikListBoxObserver::EEventItemSingleClicked ); |
|
5062 _AKNTRACE_FUNC_EXIT; |
|
5063 return; |
|
5064 } |
|
5065 } |
|
5066 else if ( s60StyleMultiselection && |
|
5067 iListBoxExt->iLastDownTappedItem == itemIndex && |
|
5068 !Buffer()->iDragToAnotherItem ) |
|
5069 { |
|
5070 iListBoxFlags |= EStateChanged; |
|
5071 Buffer()->iPressedIndex = itemIndex; |
|
5072 iView->SetAnchor(itemIndex-1); // zero indexed |
|
5073 iView->UpdateSelectionL(selectionMode); |
|
5074 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
5075 |
|
5076 // Single click item activation |
|
5077 if ( iListBoxExt->iSingleClickEnabled ) |
|
5078 { |
|
5079 iListBoxExt->EnableHighlight( EFalse ); |
|
5080 UpdateHighlightL( itemIndex ); |
|
5081 ReportListBoxEventL( |
|
5082 MEikListBoxObserver::EEventItemSingleClicked ); |
|
5083 } |
|
5084 else |
|
5085 { |
|
5086 ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked); |
|
5087 } |
|
5088 |
|
5089 UpdateMarkUnmarkMSKL(); |
|
5090 } |
|
5091 |
|
5092 if ((iListBoxFlags & EPopout) && (!(shiftKeyPressed || controlKeyPressed))) |
|
5093 ReportEventL(MCoeControlObserver::EEventRequestExit); |
|
5094 else if ((Buffer()->iPressedIndex != KEikListBoxInvalidIndex) && |
|
5095 (itemIndex==Buffer()->iPressedIndex) && |
|
5096 ( !Buffer()->iDragToAnotherItem ) && |
|
5097 (selectionMode == CListBoxView::ENoSelection)) |
|
5098 { |
|
5099 if ( iAvkonAppUi->IsTouchCompatible() ) |
|
5100 { |
|
5101 //In some cases, listbox will be blocked here for dialog(such as launch out a CAknQueryDialog). |
|
5102 //And then, if App does not wait for dialog's back, and deletes container of listbox directly, |
|
5103 //iListBoxExt will be a null point. |
|
5104 iListBoxExt->iEventModifiers = 0; |
|
5105 |
|
5106 // Clear pressed highlight and redraw item |
|
5107 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
5108 UpdateHighlightL( itemIndex ); |
|
5109 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5110 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
5111 if ( transApi && !transApi->EffectsDisabled() ) |
|
5112 { |
|
5113 DrawNow(); |
|
5114 } |
|
5115 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
5116 if ( !iListBoxExt->iSingleClickEnabled ) |
|
5117 { |
|
5118 ReportListBoxEventL(MEikListBoxObserver::EEventItemDoubleClicked); |
|
5119 } |
|
5120 _AKNTRACE_FUNC_EXIT; |
|
5121 return; |
|
5122 } |
|
5123 else |
|
5124 { |
|
5125 simulateOkKey = ETrue; |
|
5126 } |
|
5127 } |
|
5128 else |
|
5129 { |
|
5130 Buffer()->iPressedIndex=KEikListBoxInvalidIndex; |
|
5131 } |
|
5132 } |
|
5133 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
5134 iView->DrawItem( iView->CurrentItemIndex() ); |
|
5135 iListBoxExt->iIsDownOnItem = EFalse; |
|
5136 break; |
|
5137 |
|
5138 case TPointerEvent::EDrag: |
|
5139 _AKNTRACE("TPointerEvent::EDrag"); |
|
5140 // CAUTION: on hw, drag is too easy. Add a threshold for it. |
|
5141 if ( iListBoxExt->IsInIgnoreRect( pointerPos ) ) |
|
5142 { |
|
5143 break; |
|
5144 } |
|
5145 |
|
5146 if ( !hasPhysics && ( itemIndex != iView->CurrentItemIndex() ) ) |
|
5147 { |
|
5148 // If single click mode is enabled, make sure that |
|
5149 // highlight is cleared when dragging to other item. |
|
5150 if ( iListBoxExt->iSingleClickEnabled ) |
|
5151 { |
|
5152 iListBoxExt->EnableHighlight( EFalse ); |
|
5153 iListBoxExt->iLastDownTappedItem = KErrNotFound; |
|
5154 |
|
5155 // Cancel long tap animation |
|
5156 iListBoxExt->CancelLongTapL(); |
|
5157 |
|
5158 } |
|
5159 else |
|
5160 { |
|
5161 iItemDrawer->SetFlags( CListItemDrawer::EDisableHighlight ); |
|
5162 } |
|
5163 ReportListBoxEventL( MEikListBoxObserver::EEventItemDraggingActioned ); |
|
5164 } |
|
5165 |
|
5166 if( ( Buffer()->iPressedIndex != KEikListBoxInvalidIndex ) |
|
5167 && ( Buffer()->iPressedIndex != itemIndex) |
|
5168 ) |
|
5169 { |
|
5170 Buffer()->iDragToAnotherItem = ETrue; |
|
5171 |
|
5172 if ( !hasPhysics && |
|
5173 ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) ) |
|
5174 { |
|
5175 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
5176 iView->DrawItem( iView->CurrentItemIndex() ); |
|
5177 } |
|
5178 } |
|
5179 |
|
5180 if( static_cast<CAknAppUi*>(iEikonEnv->EikAppUi())->IsFaded() && !IsFocused() ) |
|
5181 { |
|
5182 iListBoxFlags&=(~ELeftDownInViewRect); |
|
5183 _AKNTRACE_FUNC_EXIT; |
|
5184 return; |
|
5185 } |
|
5186 if ( !s60StyleMultiselection ) |
|
5187 { |
|
5188 HandleDragEventL(pointerPos); |
|
5189 } |
|
5190 else |
|
5191 { |
|
5192 // selection mode needs to be disabled in multiselection lists |
|
5193 // since dragging is not supported |
|
5194 iListBoxFlags &= ~ES60StyleMultiselection; |
|
5195 HandleDragEventL( pointerPos ); |
|
5196 iListBoxFlags |= ES60StyleMultiselection; |
|
5197 } |
|
5198 break; |
|
5199 |
|
5200 case TPointerEvent::EButtonRepeat: |
|
5201 _AKNTRACE("TPointerEvent::EButtonRepeat"); |
|
5202 // CAUTION: on hw, drag is too easy. Add a threshold for it. |
|
5203 if ( iListBoxExt->IsInIgnoreRect( pointerPos ) ) |
|
5204 { |
|
5205 break; |
|
5206 } |
|
5207 |
|
5208 // make sure that highlight is cleared when dragging to other item. |
|
5209 if ( !hasPhysics && itemIndex != iView->CurrentItemIndex() ) |
|
5210 { |
|
5211 if ( iListBoxExt->iSingleClickEnabled ) |
|
5212 { |
|
5213 iListBoxExt->EnableHighlight( EFalse ); |
|
5214 iListBoxExt->iLastDownTappedItem = KErrNotFound; |
|
5215 } |
|
5216 else |
|
5217 { |
|
5218 iItemDrawer->SetFlags( CListItemDrawer::EDisableHighlight ); |
|
5219 } |
|
5220 } |
|
5221 |
|
5222 if (!(iListBoxFlags & ELeftDownInViewRect)) |
|
5223 { |
|
5224 iListBoxExt->iEventModifiers = 0; |
|
5225 _AKNTRACE_FUNC_EXIT; |
|
5226 return; |
|
5227 } |
|
5228 |
|
5229 if ( !s60StyleMultiselection ) |
|
5230 { |
|
5231 HandleDragEventL(pointerPos); |
|
5232 } |
|
5233 else |
|
5234 { |
|
5235 // selection mode needs to be disabled in multiselection lists |
|
5236 // since dragging is not supported |
|
5237 iListBoxFlags &= ~ES60StyleMultiselection; |
|
5238 HandleDragEventL( pointerPos ); |
|
5239 iListBoxFlags |= ES60StyleMultiselection; |
|
5240 } |
|
5241 break; |
|
5242 |
|
5243 default: |
|
5244 break; |
|
5245 } |
|
5246 |
|
5247 iListBoxExt->iEventModifiers = 0; |
|
5248 |
|
5249 if ( simulateOkKey ) |
|
5250 { |
|
5251 TKeyEvent keyEvent; |
|
5252 keyEvent.iCode = EKeyOK; |
|
5253 keyEvent.iScanCode = EStdKeyDevice3;// EStdKeyOK; |
|
5254 keyEvent.iRepeats = 0; |
|
5255 keyEvent.iModifiers = 0; |
|
5256 CCoeEnv::Static()->SimulateKeyEventL( keyEvent, EEventKey ); |
|
5257 } |
|
5258 _AKNTRACE_FUNC_EXIT; |
|
5259 } |
|
5260 |
|
5261 EXPORT_C void CEikListBox::SimulateArrowKeyEventL(TKeyCode aKeyCode) |
|
5262 { |
|
5263 TKeyEvent keyEvent; |
|
5264 keyEvent.iCode = aKeyCode; |
|
5265 if (iListBoxFlags & EMultipleSelection) |
|
5266 keyEvent.iModifiers = EModifierShift; |
|
5267 OfferKeyEventL(keyEvent, EEventKey); |
|
5268 } |
|
5269 |
|
5270 EXPORT_C void CEikListBox::ClearSelection() |
|
5271 { |
|
5272 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
5273 iView->ClearSelection(); |
|
5274 } |
|
5275 |
|
5276 EXPORT_C void CEikListBox::FocusChanged(TDrawNow aDrawNow) |
|
5277 { |
|
5278 _AKNTRACE_FUNC_ENTER; |
|
5279 if (iListBoxFlags & EEnterMarks || iListBoxFlags & EShiftEnterMarks ) |
|
5280 { |
|
5281 CEikButtonGroupContainer *cba; |
|
5282 MopGetObject(cba); |
|
5283 // CR PKEA-4YSASZ |
|
5284 // Unfortunately, we need to do this here. It belongs to |
|
5285 // CAknSelectionListDialog, but we need this change also |
|
5286 // to code that does not yet use CAknSelectionListDialog. |
|
5287 if (cba && IsFocused()) |
|
5288 { |
|
5289 if (iListBoxFlags & EEnterMarks) |
|
5290 { |
|
5291 TRAP_IGNORE(iAvkonEnv->CreateCbaObserverL(cba, this)); |
|
5292 } |
|
5293 if (iListBoxExt && iListBoxExt->iMSKObserverEnabled) |
|
5294 { |
|
5295 TRAP_IGNORE(iListBoxExt->CreateMSKObserverL(cba, this)); |
|
5296 } |
|
5297 } |
|
5298 else |
|
5299 { |
|
5300 if (iListBoxFlags & EEnterMarks) |
|
5301 { |
|
5302 iAvkonEnv->RemoveCbaObserver(); |
|
5303 } |
|
5304 if (iListBoxExt) |
|
5305 { |
|
5306 iListBoxExt->RemoveMSKObserver(this); |
|
5307 } |
|
5308 } |
|
5309 } |
|
5310 |
|
5311 if (IsFocused()) |
|
5312 { |
|
5313 // Some client does not let list get button1up, so we do it there... |
|
5314 if ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) |
|
5315 { |
|
5316 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
5317 DrawItem( iView->CurrentItemIndex() ); |
|
5318 } |
|
5319 iView->SetEmphasized(ETrue); |
|
5320 // This is needed or dialog pages do not work correctly. |
|
5321 // See for example multi-item fetch. |
|
5322 UpdateScrollBarThumbs(); |
|
5323 |
|
5324 if (IsMatchBuffer()) |
|
5325 iView->DrawMatcherCursor(); |
|
5326 if ( iListBoxFlags & EPaintedSelection ) // added |
|
5327 { |
|
5328 TRAP_IGNORE(iView->SelectItemL(CurrentItemIndex())); |
|
5329 } |
|
5330 } |
|
5331 else |
|
5332 { |
|
5333 // switch off selection (marking) mode when we lose focus |
|
5334 // this also corrects situation, where FEP-menu is launched |
|
5335 // and thus listbox doesn't receive shift up event |
|
5336 if (NULL != iListBoxExt) |
|
5337 { |
|
5338 if ((iListBoxFlags & EMultipleSelection) && (iListBoxFlags & EShiftEnterMarks)) |
|
5339 { |
|
5340 iListBoxExt->iShiftKeyPressed = EFalse; |
|
5341 if (iListBoxExt->iLongPressTimer && iListBoxExt->iLongPressTimer->IsActive()) |
|
5342 { |
|
5343 iListBoxExt->iLongPressTimer->Cancel(); |
|
5344 } |
|
5345 ChangeSelectionMode(EFalse); |
|
5346 iListBoxExt->iSelectionModeEnabled = EFalse; |
|
5347 } |
|
5348 |
|
5349 // Cancel long tap detecting if focus is lost |
|
5350 iListBoxExt->CancelLongTapL(); |
|
5351 } |
|
5352 |
|
5353 iView->SetEmphasized(EFalse); |
|
5354 iView->HideMatcherCursor(); |
|
5355 |
|
5356 if (iItemEditor && |
|
5357 (iListBoxFlags & EPaintedSelection) && |
|
5358 (NULL != iListBoxExt && iListBoxExt->ReasonForFocusLost() == EFocusLostToExternalControl)) |
|
5359 { |
|
5360 iView->DeselectItem(CurrentItemIndex()); |
|
5361 } |
|
5362 } |
|
5363 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5364 // LISTBOX EFFECTS IMPLEMENTATION |
|
5365 if ( aDrawNow && !CAknListLoader::TfxApiInternal( iView->iGc ) ) |
|
5366 #else |
|
5367 if (aDrawNow) |
|
5368 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
5369 { |
|
5370 // redraw items affected by change in emphasis |
|
5371 TInt numOfSelectedItems = iView->SelectionIndexes()->Count(); |
|
5372 TInt selectionIndex = 0; |
|
5373 for (TInt i = 0; i < numOfSelectedItems; i++) |
|
5374 { |
|
5375 selectionIndex = (*(iView->SelectionIndexes()))[i]; |
|
5376 if (ItemExists(selectionIndex)) |
|
5377 iView->DrawItem(selectionIndex); |
|
5378 } |
|
5379 } |
|
5380 _AKNTRACE_FUNC_EXIT; |
|
5381 } |
|
5382 |
|
5383 EXPORT_C void CEikListBox::SetDimmed(TBool aDimmed) |
|
5384 { |
|
5385 // should panic if view does not exist |
|
5386 CCoeControl::SetDimmed(aDimmed); |
|
5387 iView->SetDimmed(aDimmed); |
|
5388 HandleResourceChange(KEikMessageColorSchemeChange); |
|
5389 } |
|
5390 |
|
5391 EXPORT_C void CEikListBox::ClearMatchBuffer() const |
|
5392 { |
|
5393 if(IsMatchBuffer()) |
|
5394 { |
|
5395 iView->SetMatcherCursorPos(0); |
|
5396 MatchBuffer()->Clear(); |
|
5397 } |
|
5398 } |
|
5399 |
|
5400 // |
|
5401 // Shortcut support functions (no default implementation available) |
|
5402 // |
|
5403 EXPORT_C TInt CEikListBox::ShortcutValueForNextList() |
|
5404 { |
|
5405 //__ASSERT_DEBUG(0,Panic(EEikPanicInvalidUseOfListBoxShortcuts)); |
|
5406 return 0; |
|
5407 } |
|
5408 EXPORT_C void CEikListBox::SetShortcutValueFromPrevList(TInt /*aValue*/) |
|
5409 { |
|
5410 //__ASSERT_DEBUG(0,Panic(EEikPanicInvalidUseOfListBoxShortcuts)); |
|
5411 } |
|
5412 |
|
5413 // pop-up positioning support |
|
5414 EXPORT_C TRect CEikListBox::HighlightRect() const |
|
5415 { |
|
5416 TPoint topLeft( View()->ItemPos( CurrentItemIndex() ) ); |
|
5417 topLeft += iAvkonAppUi->ClientRect().iTl; |
|
5418 |
|
5419 TRect rect( topLeft, iItemDrawer->ItemCellSize() ); |
|
5420 |
|
5421 return rect; |
|
5422 } |
|
5423 |
|
5424 EXPORT_C TBool CEikListBox::BackgroundDrawingSuppressed() const |
|
5425 { |
|
5426 if ( iListBoxExt ) |
|
5427 { |
|
5428 return iListBoxExt->iBackgroundDrawingSuppressed; |
|
5429 } |
|
5430 |
|
5431 return EFalse; |
|
5432 } |
|
5433 |
|
5434 // Series 60 needs this to control the state machine that determines how |
|
5435 // shortcuts work. |
|
5436 EXPORT_C TBool CEikListBox::LastCharMatched() const |
|
5437 { |
|
5438 return iLastCharMatched; |
|
5439 } |
|
5440 |
|
5441 EXPORT_C void CEikListBox::MatchTypedCharL(TUint aCode) |
|
5442 { |
|
5443 _AKNTRACE_FUNC_ENTER; |
|
5444 iLastCharMatched = EFalse; |
|
5445 if (iListBoxFlags&ENoFirstLetterMatching) |
|
5446 { |
|
5447 _AKNTRACE_FUNC_EXIT; |
|
5448 return; |
|
5449 } |
|
5450 const MDesCArray* matchableTextArray = iModel->MatchableTextArray(); |
|
5451 if (! matchableTextArray) |
|
5452 { |
|
5453 _AKNTRACE_FUNC_EXIT; |
|
5454 return; |
|
5455 } |
|
5456 if (IsMatchBuffer()) |
|
5457 { |
|
5458 TInt matcherCursorPos = iView->MatcherCursorPos(); |
|
5459 if (MatchBuffer()->MatchLength() == KEikMaxMatchingBufferLength) |
|
5460 { |
|
5461 _AKNTRACE_FUNC_EXIT; |
|
5462 return; |
|
5463 } |
|
5464 MatchBuffer()->AppendChar(aCode); |
|
5465 TInt selectedItemIndex; |
|
5466 TInt ret = MatchBuffer()->FirstMatchingIndexF(selectedItemIndex, *matchableTextArray); |
|
5467 if (ret == KErrNone) |
|
5468 { |
|
5469 ++matcherCursorPos; |
|
5470 /* |
|
5471 if (matcherCursorPos >= matchableTextArray->MdcaPoint(selectedItemIndex).Length()) |
|
5472 { |
|
5473 iListBoxExt->iBuffer->iMatchBuffer->DeleteLastChar(); |
|
5474 --matcherCursorPos; |
|
5475 } |
|
5476 */ |
|
5477 iView->VerticalMoveToItemL(selectedItemIndex, CListBoxView::ESingleSelection); |
|
5478 // SetCurrentItemIndexAndDraw(selectedItemIndex); |
|
5479 iView->SetMatcherCursorPos(matcherCursorPos); |
|
5480 iLastCharMatched = ETrue; |
|
5481 } |
|
5482 else // No match with buf with new letter: discard new char |
|
5483 { |
|
5484 iLastCharMatched = EFalse; |
|
5485 MatchBuffer()->DeleteLastChar(); |
|
5486 } |
|
5487 } |
|
5488 else |
|
5489 { |
|
5490 // do first later matching here |
|
5491 TChar matchCharacter(aCode); |
|
5492 matchCharacter.Fold(); |
|
5493 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
5494 TChar firstCharOfItem; |
|
5495 TBool foundMatch = EFalse; |
|
5496 TInt itemIndex = currentItemIndex + 1; |
|
5497 // look for match, starting at item below the current one |
|
5498 while ((itemIndex != currentItemIndex) && !foundMatch) |
|
5499 { |
|
5500 // if end of list reached, restart search from the beginning of the list |
|
5501 if (ItemExists(itemIndex) == EFalse) |
|
5502 { |
|
5503 itemIndex = 0; |
|
5504 if (itemIndex == currentItemIndex) |
|
5505 { |
|
5506 foundMatch = ETrue; |
|
5507 break; |
|
5508 } |
|
5509 } |
|
5510 TPtrC buf=matchableTextArray->MdcaPoint(itemIndex); |
|
5511 if (buf.Length()) |
|
5512 { |
|
5513 firstCharOfItem = buf[0]; |
|
5514 firstCharOfItem.Fold(); |
|
5515 if (matchCharacter == firstCharOfItem) |
|
5516 { |
|
5517 foundMatch = ETrue; |
|
5518 break; |
|
5519 } |
|
5520 } |
|
5521 ++itemIndex; |
|
5522 } |
|
5523 if (foundMatch) |
|
5524 { |
|
5525 iLastCharMatched = ETrue; |
|
5526 // SetCurrentItemIndexAndDraw(itemIndex); |
|
5527 iView->VerticalMoveToItemL(itemIndex, CListBoxView::ESingleSelection); |
|
5528 } |
|
5529 } |
|
5530 _AKNTRACE_FUNC_EXIT; |
|
5531 } |
|
5532 |
|
5533 EXPORT_C void CEikListBox::UndoLastChar() |
|
5534 { |
|
5535 __ASSERT_DEBUG(MatchBuffer(), Panic(EEikPanicListBoxNoMatchBuffer)); |
|
5536 __ASSERT_DEBUG(iModel->MatchableTextArray(), Panic(EEikPanicListBoxNoMatchTextArray)); |
|
5537 iView->SetMatcherCursorPos(iView->MatcherCursorPos() - 1); |
|
5538 MatchBuffer()->DeleteLastChar(); |
|
5539 TInt selectedItemIndex; |
|
5540 const MDesCArray* matchableTextArray = iModel->MatchableTextArray(); |
|
5541 TInt retcode = MatchBuffer()->FirstMatchingIndexF(selectedItemIndex, *matchableTextArray); |
|
5542 if (!retcode) |
|
5543 SetCurrentItemIndexAndDraw(selectedItemIndex); |
|
5544 } |
|
5545 |
|
5546 EXPORT_C void CEikListBox::SetLaunchingButton(CEikButtonBase* aButton) |
|
5547 { |
|
5548 iLaunchingButton=aButton; |
|
5549 } |
|
5550 |
|
5551 EXPORT_C TCoeInputCapabilities CEikListBox::InputCapabilities() const |
|
5552 { |
|
5553 if (iListBoxFlags&EIncrementalMatching) |
|
5554 return TCoeInputCapabilities(TCoeInputCapabilities::ENavigation|TCoeInputCapabilities::EAllText); |
|
5555 if (iListBoxFlags&ENoFirstLetterMatching) |
|
5556 return TCoeInputCapabilities(TCoeInputCapabilities::ENavigation); |
|
5557 return TCoeInputCapabilities(TCoeInputCapabilities::ENavigation|TCoeInputCapabilities::EAllText/*,1*/); |
|
5558 } |
|
5559 |
|
5560 /** |
|
5561 * @ since uikon_1.2 |
|
5562 * A method which returns a TMargins object for the list box. |
|
5563 * The TMargins object has 4 values, one for each side of the list box. |
|
5564 * Depending on use of the Laf, the DFRD can program 2, 3 or 4 margins ... |
|
5565 * ... but although the application developer can see up to 4 different margins ... |
|
5566 * ... they can only set 2 (ie. iHorizontalMargin and iVerticalMargin) |
|
5567 */ |
|
5568 EXPORT_C TMargins8 CEikListBox::ListBoxMargins() const |
|
5569 { |
|
5570 /* |
|
5571 TMargins margins; |
|
5572 if(iHorizontalMargin == KLafListBoxUseLafHorizMargins) // if the Laf is being used |
|
5573 { |
|
5574 margins.iLeft = LafListBox::LeftMargin(); |
|
5575 margins.iRight = LafListBox::RightMargin(); |
|
5576 } |
|
5577 else |
|
5578 { |
|
5579 // SERIES60 LAF |
|
5580 margins.iLeft=HorizontalMargin(); |
|
5581 margins.iRight=0; |
|
5582 // END OF SERIES60 LAF |
|
5583 } |
|
5584 if(iVerticalMargin == KLafListBoxUseLafVertMargins) // if the Laf is being used |
|
5585 { |
|
5586 margins.iTop = LafListBox::TopMargin(); |
|
5587 margins.iBottom = LafListBox::BottomMargin(); |
|
5588 } |
|
5589 else |
|
5590 { |
|
5591 // SERIES60 LAF |
|
5592 margins.iTop=VerticalMargin(); |
|
5593 margins.iBottom = 0; |
|
5594 // END OF SERIES60 LAF |
|
5595 |
|
5596 // Old implementation (not good for Series 60) |
|
5597 //margins.iTop=margins.iBottom=VerticalMargin(); |
|
5598 // |
|
5599 |
|
5600 } |
|
5601 */ |
|
5602 // SERIES60 LAF |
|
5603 TMargins8 margins = iMargins ; |
|
5604 margins.iTop=TInt8(VerticalMargin()); |
|
5605 margins.iBottom = 0; |
|
5606 margins.iLeft=TInt8(HorizontalMargin()); |
|
5607 margins.iRight = 0; |
|
5608 // END OF SERIES60 LAF |
|
5609 return margins; |
|
5610 } |
|
5611 |
|
5612 /** |
|
5613 * @ deprecated |
|
5614 * Use CEikListBox::ListBoxMargins() instead, to get more accurate values, |
|
5615 * as use of this method may cause a single pixel error if the laf |
|
5616 * is being used, due to the bit shifting involved |
|
5617 */ |
|
5618 EXPORT_C TInt CEikListBox::HorizontalMargin() const |
|
5619 { |
|
5620 return ((iMargins.iLeft + iMargins.iRight) >> 1); |
|
5621 } |
|
5622 |
|
5623 /** |
|
5624 * @ deprecated |
|
5625 * Use CEikListBox::ListBoxMargins() instead, to get more accurate values, |
|
5626 * as use of this method may cause a single pixel error if the laf |
|
5627 * is being used, due to the bit shifting involved |
|
5628 */ |
|
5629 EXPORT_C TInt CEikListBox::VerticalMargin() const |
|
5630 { |
|
5631 return ((iMargins.iTop + iMargins.iBottom) >> 1); |
|
5632 } |
|
5633 |
|
5634 EXPORT_C void CEikListBox::SetVerticalMargin(TInt aMargin) |
|
5635 { |
|
5636 iMargins.iTop = iMargins.iBottom = (TInt8) aMargin; |
|
5637 } |
|
5638 |
|
5639 EXPORT_C void CEikListBox::SetHorizontalMargin(TInt aMargin) |
|
5640 { |
|
5641 iMargins.iLeft = iMargins.iRight = (TInt8) aMargin; |
|
5642 } |
|
5643 |
|
5644 EXPORT_C RIncrMatcherBase* CEikListBox::MatchBuffer() const |
|
5645 { |
|
5646 if(CONST_CAST(CEikListBox*,this)->CheckCreateExtension() && Buffer()) |
|
5647 return Buffer()->iMatchBuffer; |
|
5648 return NULL; |
|
5649 } |
|
5650 |
|
5651 EXPORT_C TInt CEikListBox::ViewRectHeightAdjustment() const |
|
5652 { |
|
5653 return iViewRectHeightAdjustment; |
|
5654 } |
|
5655 |
|
5656 EXPORT_C void CEikListBox::SetViewRectHeightAdjustment(TInt aAdjustment) |
|
5657 { |
|
5658 iViewRectHeightAdjustment = aAdjustment; |
|
5659 } |
|
5660 |
|
5661 EXPORT_C TRgb CEikListBox::BackColor() const |
|
5662 { |
|
5663 return iBackColor; |
|
5664 } |
|
5665 |
|
5666 EXPORT_C TInt CEikListBox::VerticalInterItemGap() const |
|
5667 { |
|
5668 return KEikListBoxItemVGap; |
|
5669 // return ListBoxLaf()->LBxItemVGap(); |
|
5670 } |
|
5671 |
|
5672 /** |
|
5673 * Gets the list of logical colors employed in the drawing of the control, |
|
5674 * paired with an explanation of how they are used. Appends the list to aColorUseList. |
|
5675 * |
|
5676 * @since ER5U |
|
5677 */ |
|
5678 EXPORT_C void CEikListBox::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const |
|
5679 { |
|
5680 CEikBorderedControl::GetColorUseListL(aColorUseList); |
|
5681 LafListBox::GetColorUseListL(aColorUseList); |
|
5682 } |
|
5683 |
|
5684 /** |
|
5685 * Handles a change to the control's resources of type aType |
|
5686 * which are shared across the environment, e.g. colors or fonts. |
|
5687 * |
|
5688 * @since ER5U |
|
5689 */ |
|
5690 EXPORT_C void CEikListBox::HandleResourceChange(TInt aType) |
|
5691 { |
|
5692 _AKNTRACE_FUNC_ENTER; |
|
5693 _AKNTRACE( "aType = %d", aType ); |
|
5694 CEikBorderedControl::HandleResourceChange(aType); |
|
5695 |
|
5696 if(aType==KEikDynamicLayoutVariantSwitch) |
|
5697 { |
|
5698 if( iListBoxExt && iListBoxExt->iPhysics ) |
|
5699 { |
|
5700 //stop flicking |
|
5701 iListBoxExt->iPhysics->StopPhysics(); |
|
5702 |
|
5703 //If touch down and hold view, |
|
5704 //kinetic scrolling should not be started after rotate screen. |
|
5705 iListBoxFlags &= ( ~ELeftDownInViewRect ); |
|
5706 } |
|
5707 |
|
5708 if ( iView ) |
|
5709 { |
|
5710 iView->SetItemOffsetInPixels( 0 ); |
|
5711 } |
|
5712 |
|
5713 // make sure that highlight is removed and long tap is canceled |
|
5714 // on layout switch, if single click is enabled and there is |
|
5715 // pointer down on any item |
|
5716 if ( iListBoxExt && iListBoxExt->iSingleClickEnabled |
|
5717 && iListBoxExt->iLastDownTappedItem != KErrNotFound ) |
|
5718 { |
|
5719 iListBoxExt->EnableHighlight( EFalse ); |
|
5720 iListBoxExt->CancelLongTapL(); |
|
5721 } |
|
5722 |
|
5723 SizeChanged(); |
|
5724 |
|
5725 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5726 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
5727 if ( transApi ) |
|
5728 { |
|
5729 transApi->Remove( MAknListBoxTfxInternal:: EListEverything ); |
|
5730 } |
|
5731 #endif |
|
5732 } |
|
5733 |
|
5734 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5735 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc ); |
|
5736 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
5737 |
|
5738 if ( aType == KEikMessageColorSchemeChange || aType == KAknsMessageSkinChange ) |
|
5739 { |
|
5740 if ( !CAknEnv::Static()->TransparencyEnabled() && OwnsWindow()) |
|
5741 { |
|
5742 Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorControlBackground,*this)); |
|
5743 } |
|
5744 iBackColor=iEikonEnv->ControlColor(IsDimmed() ? |
|
5745 EColorControlDimmedBackground : EColorControlBackground,*this); |
|
5746 UpdateViewColors(); |
|
5747 UpdateItemDrawerColors(); |
|
5748 |
|
5749 SizeChanged(); |
|
5750 UpdateScrollBarsColors(); |
|
5751 |
|
5752 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
5753 if ( transApi ) |
|
5754 { |
|
5755 transApi->Remove( MAknListBoxTfxInternal:: EListEverything ); |
|
5756 } |
|
5757 } |
|
5758 else if ( transApi && aType == KEikMessageUnfadeWindows && IsReadyToDraw() ) |
|
5759 { |
|
5760 DrawDeferred(); |
|
5761 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
5762 } |
|
5763 |
|
5764 switch ( aType ) |
|
5765 { |
|
5766 case KEikMessageWindowsFadeChange: |
|
5767 { |
|
5768 if ( iListBoxExt ) |
|
5769 { |
|
5770 iListBoxExt->ReportCollectionChangedEvent(); |
|
5771 } |
|
5772 } // fall through |
|
5773 case KEikMessageUnfadeWindows: |
|
5774 case KEikMessageFadeAllWindows: |
|
5775 { |
|
5776 // Some client does not let list get button1up, so we do it there... |
|
5777 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
5778 TInt index = View()->CurrentItemIndex(); |
|
5779 if ( index != KErrNotFound ) |
|
5780 { |
|
5781 Window().Invalidate( TRect( View()->ItemPos(index), |
|
5782 View()->ItemSize() ) ); |
|
5783 } |
|
5784 break; |
|
5785 } |
|
5786 case KEikDynamicLayoutVariantSwitch: |
|
5787 case KEikMessageColorSchemeChange: |
|
5788 case KAknsMessageSkinChange: |
|
5789 DrawDeferred(); |
|
5790 break; |
|
5791 |
|
5792 case KAknMessageFocusLost: |
|
5793 { |
|
5794 if ( iListBoxExt && iListBoxExt->iSingleClickEnabled ) |
|
5795 { |
|
5796 TBool enabled( iItemDrawer && !( iItemDrawer->Flags() |
|
5797 & CListItemDrawer::ESingleClickDisabledHighlight ) ); |
|
5798 |
|
5799 if ( enabled ) |
|
5800 { |
|
5801 iListBoxExt->EnableHighlight( EFalse ); |
|
5802 if ( iView && IsVisible() ) |
|
5803 { |
|
5804 iView->DrawItem( CurrentItemIndex() ); |
|
5805 } |
|
5806 } |
|
5807 } |
|
5808 } |
|
5809 break; |
|
5810 } |
|
5811 _AKNTRACE_FUNC_EXIT; |
|
5812 } |
|
5813 |
|
5814 void CEikListBox::UpdateScrollBarsColors() |
|
5815 { |
|
5816 } |
|
5817 |
|
5818 void CEikListBox::UpdateScrollBarColors(CEikScrollBar* /*aScrollBar*/) |
|
5819 { |
|
5820 } |
|
5821 |
|
5822 //----------------------------------------------------------- |
|
5823 // CEikListBox::IsMultiselection() |
|
5824 // Returns true if ES60StyleMultiselection flag is on |
|
5825 //----------------------------------------------------------- |
|
5826 EXPORT_C TBool CEikListBox::IsMultiselection() |
|
5827 { |
|
5828 /* note, that this method is very misleading. To have this method |
|
5829 * return true, you need to construct your listbox with |
|
5830 * EAknListBoxPointerMultiselectionList flag, not with |
|
5831 * EAknListBoxMultipleSelection as ES60StyleMultiselection might |
|
5832 * suggest. However, to make multiselection work, you need |
|
5833 * to or those flags together... |
|
5834 */ |
|
5835 return (iListBoxFlags & ES60StyleMultiselection ); |
|
5836 } |
|
5837 |
|
5838 //----------------------------------------------------------- |
|
5839 // CEikListBox::EventModifiers() |
|
5840 // Returns pointerevent modifiers. |
|
5841 //----------------------------------------------------------- |
|
5842 EXPORT_C TInt CEikListBox::EventModifiers() |
|
5843 { |
|
5844 if (iListBoxExt) |
|
5845 { |
|
5846 return iListBoxExt->iEventModifiers; |
|
5847 } |
|
5848 return NULL; |
|
5849 } |
|
5850 |
|
5851 EXPORT_C void CEikListBox::CEikListBox_Reserved() |
|
5852 {} |
|
5853 |
|
5854 TBool CEikListBox::CheckCreateExtension() |
|
5855 { |
|
5856 TInt err=KErrNone; |
|
5857 if (!iListBoxExt) |
|
5858 { |
|
5859 TRAP(err,iListBoxExt=CListBoxExt::NewL(*this)); |
|
5860 } |
|
5861 return err==KErrNone; |
|
5862 } |
|
5863 |
|
5864 void CEikListBox::CheckCreateExtensionL() |
|
5865 { |
|
5866 if (!iListBoxExt) |
|
5867 iListBoxExt=CListBoxExt::NewL(*this); |
|
5868 } |
|
5869 |
|
5870 void CEikListBox::CheckCreateBufferL() |
|
5871 { |
|
5872 CheckCreateExtensionL(); |
|
5873 iListBoxExt->CheckCreateBufferL(); |
|
5874 } |
|
5875 |
|
5876 CMatchBuffer* CEikListBox::Buffer() const |
|
5877 { |
|
5878 if(CONST_CAST(CEikListBox*,this)->CheckCreateExtension()) |
|
5879 return iListBoxExt->Buffer(); |
|
5880 return NULL; |
|
5881 } |
|
5882 |
|
5883 EXPORT_C TBool CEikListBox::IsMatchBuffer() const |
|
5884 { |
|
5885 return (CONST_CAST(CEikListBox*,this)->CheckCreateExtension() && iListBoxExt->IsMatchBuffer()); |
|
5886 } |
|
5887 |
|
5888 EXPORT_C void CEikListBox::SetReasonForFocusLostL(TReasonForFocusLost aReasonForFocusLost) |
|
5889 { |
|
5890 CheckCreateExtensionL(); |
|
5891 iListBoxExt->SetReasonForFocusLost(aReasonForFocusLost); |
|
5892 } |
|
5893 |
|
5894 EXPORT_C CEikListBox::TReasonForFocusLost CEikListBox::ReasonForFocusLostL() |
|
5895 { |
|
5896 CheckCreateExtensionL(); |
|
5897 return iListBoxExt->ReasonForFocusLost(); |
|
5898 } |
|
5899 |
|
5900 /** |
|
5901 * Sets the item editor to aEditor and transfers ownership. |
|
5902 * |
|
5903 * @since ER5U |
|
5904 */ |
|
5905 EXPORT_C void CEikListBox::SetItemEditor(MEikListBoxEditor* aEditor) |
|
5906 { |
|
5907 if (iItemEditor) |
|
5908 iItemEditor->Release(); |
|
5909 iItemEditor=aEditor; |
|
5910 } |
|
5911 |
|
5912 /** |
|
5913 * Deletes and NULLs the item editor. |
|
5914 * |
|
5915 * @since ER5U |
|
5916 */ |
|
5917 EXPORT_C void CEikListBox::ResetItemEditor() |
|
5918 { |
|
5919 if (iItemEditor) |
|
5920 iItemEditor->Release(); |
|
5921 iItemEditor=NULL; |
|
5922 } |
|
5923 |
|
5924 /** |
|
5925 * Returns a pointer to the item editor. Does not imply transfer of ownership. |
|
5926 * |
|
5927 * @since ER5U |
|
5928 */ |
|
5929 EXPORT_C MEikListBoxEditor* CEikListBox::ItemEditor() |
|
5930 { |
|
5931 return iItemEditor; |
|
5932 } |
|
5933 |
|
5934 /** |
|
5935 * Creates an item editor, if one does not already exist, and starts editing the |
|
5936 * current item up to a maximum length of aMaxLength characters. Also reports an |
|
5937 * EEventEditingStarted event to any list box observer by default. |
|
5938 * |
|
5939 * @since ER5U |
|
5940 */ |
|
5941 EXPORT_C void CEikListBox::EditItemL(TInt aMaxLength) |
|
5942 { |
|
5943 _AKNTRACE_FUNC_ENTER; |
|
5944 CEikListBoxTextEditor* itemEditor = STATIC_CAST(CEikListBoxTextEditor*,ItemEditor()); |
|
5945 if ( !itemEditor || (itemEditor && !(itemEditor->Editor())) ) |
|
5946 { |
|
5947 SetItemEditor(new(ELeave) CEikListBoxTextEditor(Model())); |
|
5948 itemEditor = STATIC_CAST(CEikListBoxTextEditor*,ItemEditor()); |
|
5949 const TInt index = View()->CurrentItemIndex(); |
|
5950 itemEditor->SetFont( ((CTextListItemDrawer*)iItemDrawer)->Font(index) ); |
|
5951 TRect rect = TRect( View()->ItemPos( index ), View()->ItemSize() ); |
|
5952 rect.iTl.iX += LafListBox::InnerGutter(); |
|
5953 if (iItemDrawer->Flags()&CListItemDrawer::EDrawMarkSelection) |
|
5954 { |
|
5955 rect.iTl.iX += iItemDrawer->MarkColumn() + iItemDrawer->MarkGutter(); |
|
5956 } |
|
5957 iListBoxExt->SetReasonForFocusLost(EFocusLostToInternalEditor); |
|
5958 itemEditor->StartEditingL(*this,rect,index,aMaxLength); |
|
5959 iListBoxExt->SetReasonForFocusLost(EFocusLostToExternalControl); |
|
5960 ReportListBoxEventL( MEikListBoxObserver::EEventEditingStarted ); |
|
5961 } |
|
5962 _AKNTRACE_FUNC_EXIT; |
|
5963 } |
|
5964 |
|
5965 /** |
|
5966 * Stops editing and deletes the item editor, reporting an EEventEditingStopped event |
|
5967 * to any list box observer. Updates the list box model if aUpdateModel is ETrue. |
|
5968 * |
|
5969 * @since ER5U |
|
5970 */ |
|
5971 EXPORT_C void CEikListBox::StopEditingL( TBool aUpdateModel ) |
|
5972 { |
|
5973 MEikListBoxEditor* editor = ItemEditor(); |
|
5974 if ( editor ) |
|
5975 { |
|
5976 if ( aUpdateModel ) editor->UpdateModelL(); |
|
5977 editor->StopEditingL(); |
|
5978 ResetItemEditor(); |
|
5979 ReportListBoxEventL( MEikListBoxObserver::EEventEditingStopped ); |
|
5980 } |
|
5981 } |
|
5982 |
|
5983 EXPORT_C CEikScrollBarFrame* CEikListBox::CreateScrollBarFrameL(TBool aPreAlloc, TBool aRemote) |
|
5984 { |
|
5985 // CEikListBox creates a window owning scroll bar by default. This causes |
|
5986 // scroll bar flicker during listbox open when transparency is enabled. |
|
5987 // With CAknPopupList the listbox and scroll bar are created outside of |
|
5988 // the CAknPopupList component. In order not to have to change source |
|
5989 // code of all CAknPopupList users to create a non window owning scroll |
|
5990 // bar, the default is changed for this case. |
|
5991 _AKNTRACE_FUNC_ENTER; |
|
5992 TBool windowOwning = ETrue; |
|
5993 if (Parent()) |
|
5994 { |
|
5995 CAknPopupList* popupList; |
|
5996 Parent()->MopGetObjectNoChaining(popupList); |
|
5997 if (popupList) |
|
5998 { |
|
5999 windowOwning = EFalse; |
|
6000 } |
|
6001 } |
|
6002 _AKNTRACE_FUNC_EXIT; |
|
6003 return CreateScrollBarFrameL(aPreAlloc, aRemote, windowOwning); |
|
6004 } |
|
6005 |
|
6006 EXPORT_C CEikScrollBarFrame* CEikListBox::CreateScrollBarFrameL(TBool aPreAlloc, TBool aRemote, TBool aWindowOwning) |
|
6007 { |
|
6008 _AKNTRACE_FUNC_ENTER; |
|
6009 if (!iSBFrame) |
|
6010 { |
|
6011 iSBFrame=new(ELeave) CEikScrollBarFrame(this, this, aPreAlloc, ETrue); |
|
6012 |
|
6013 // Check which type of scrollbar is to be shown |
|
6014 if (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan) |
|
6015 { |
|
6016 iSBFrame->CreateDoubleSpanScrollBarsL(aWindowOwning, aRemote, ETrue, EFalse); |
|
6017 |
|
6018 if ( CAknEnv::Static()->TransparencyEnabled() && iListBoxExt && iListBoxExt->iPhysics ) |
|
6019 { |
|
6020 iSBFrame->DrawBackground(EFalse,EFalse); |
|
6021 } |
|
6022 } |
|
6023 |
|
6024 if (CheckCreateExtension()) |
|
6025 iListBoxExt->SetUpdateScrollBarsColors(ETrue); |
|
6026 if(aRemote) |
|
6027 iSBFrameOwned = EOwnedExternally; |
|
6028 else |
|
6029 iSBFrameOwned = ENotOwnedExternally; |
|
6030 } |
|
6031 _AKNTRACE_FUNC_EXIT; |
|
6032 return iSBFrame; |
|
6033 } |
|
6034 |
|
6035 EXPORT_C void CEikListBox::EnableMSKObserver(TBool aEnable) |
|
6036 { |
|
6037 _AKNTRACE_FUNC_ENTER; |
|
6038 if (iListBoxExt) |
|
6039 { |
|
6040 if (aEnable == EFalse) |
|
6041 { |
|
6042 iListBoxExt->RemoveMSKObserver(this); // remove disabled observer |
|
6043 } |
|
6044 else |
|
6045 { |
|
6046 if (iListBoxFlags & EEnterMarks || iListBoxFlags & EShiftEnterMarks) |
|
6047 { |
|
6048 CEikButtonGroupContainer *cba; |
|
6049 MopGetObject(cba); |
|
6050 if (cba) |
|
6051 { |
|
6052 TRAP_IGNORE(iListBoxExt->CreateMSKObserverL(cba, this)); |
|
6053 TRAP_IGNORE(UpdateMarkUnmarkMSKL()); |
|
6054 } |
|
6055 } |
|
6056 } |
|
6057 iListBoxExt->iMSKObserverEnabled = aEnable; |
|
6058 } |
|
6059 _AKNTRACE_FUNC_EXIT; |
|
6060 } |
|
6061 |
|
6062 void CEikListBox::DoShiftMSKMarkingL() |
|
6063 { |
|
6064 _AKNTRACE_FUNC_ENTER; |
|
6065 if ( iListBoxExt && iListBoxExt->iWesternVariant && |
|
6066 ( iListBoxFlags & EShiftEnterMarks || iListBoxFlags & EEnterMarks ) ) |
|
6067 { |
|
6068 // if the user marks item with hash+MSK, releasing MSK should not |
|
6069 // do the marking again |
|
6070 iListBoxExt->iShortHashMark = EFalse; |
|
6071 |
|
6072 iView->UpdateSelectionL(CListBoxView::EDisjointSelection); |
|
6073 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
6074 UpdateMarkUnmarkMSKL(); |
|
6075 } |
|
6076 _AKNTRACE_FUNC_EXIT; |
|
6077 } |
|
6078 |
|
6079 |
|
6080 // --------------------------------------------------------------------------- |
|
6081 // Disables the kinetic scrolling functionality in the list. |
|
6082 // --------------------------------------------------------------------------- |
|
6083 // |
|
6084 EXPORT_C void CEikListBox::DisableScrolling( TBool aDisabled ) |
|
6085 { |
|
6086 _AKNTRACE_FUNC_ENTER; |
|
6087 iListBoxExt->iScrollingDisabled = aDisabled; |
|
6088 iView->iExtension->iScrollingDisabled = aDisabled; |
|
6089 |
|
6090 if ( aDisabled && iListBoxExt->iPhysics ) |
|
6091 { |
|
6092 delete iListBoxExt->iPhysics; |
|
6093 iListBoxExt->iPhysics = NULL; |
|
6094 iView->SetItemOffsetInPixels( 0 ); |
|
6095 } |
|
6096 else if ( !aDisabled && !iListBoxExt->iPhysics && CAknPhysics::FeatureEnabled() ) |
|
6097 { |
|
6098 iListBoxExt->iPhysics = CAknPhysics::NewL( *iListBoxExt, this); |
|
6099 } |
|
6100 _AKNTRACE_FUNC_EXIT; |
|
6101 } |
|
6102 |
|
6103 |
|
6104 // --------------------------------------------------------------------------- |
|
6105 // Checks if the kinetic scrolling functionality is disabled in the list. |
|
6106 // --------------------------------------------------------------------------- |
|
6107 // |
|
6108 EXPORT_C TBool CEikListBox::ScrollingDisabled() |
|
6109 { |
|
6110 return !iListBoxExt->iPhysics || iListBoxExt->iScrollingDisabled; |
|
6111 } |
|
6112 |
|
6113 |
|
6114 EXPORT_C void CEikListBox::SetPointerEventFilterDisabledL( const CArrayFix<TInt>& aItemIndexes ) |
|
6115 { |
|
6116 _AKNTRACE_FUNC_ENTER; |
|
6117 iListBoxExt->iMutiTappingItems.Reset(); |
|
6118 |
|
6119 for(TInt i=0; i<aItemIndexes.Count(); i++ ) |
|
6120 { |
|
6121 iListBoxExt->iMutiTappingItems.InsertInOrderL( aItemIndexes.At(i) ); |
|
6122 } |
|
6123 _AKNTRACE_FUNC_EXIT; |
|
6124 } |
|
6125 |
|
6126 |
|
6127 // --------------------------------------------------------------------------- |
|
6128 // CEikListBox::SuspendEffects |
|
6129 // --------------------------------------------------------------------------- |
|
6130 // |
|
6131 EXPORT_C void CEikListBox::SuspendEffects( TBool aSuspend ) |
|
6132 { |
|
6133 _AKNTRACE_FUNC_ENTER; |
|
6134 TBool effectsEnabled = EFalse; |
|
6135 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6136 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( |
|
6137 iView->ItemDrawer()->Gc() ); |
|
6138 |
|
6139 effectsEnabled = transApi && !transApi->EffectsDisabled(); |
|
6140 #endif |
|
6141 // Record effect's state before those are suspended so that calling this |
|
6142 // method doesn't turn effects on if they were disabled already. |
|
6143 if ( iListBoxExt ) |
|
6144 { |
|
6145 if ( effectsEnabled && !iListBoxExt->iEffectsEnabled ) |
|
6146 { |
|
6147 iListBoxExt->iEffectsEnabled = ETrue; |
|
6148 } |
|
6149 |
|
6150 if ( !aSuspend ) |
|
6151 { |
|
6152 aSuspend = !iListBoxExt->iEffectsEnabled; |
|
6153 } |
|
6154 } |
|
6155 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6156 |
|
6157 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iView->ItemDrawer()->Gc() ); |
|
6158 |
|
6159 if ( aSuspend && effectsEnabled && tfxApi ) |
|
6160 { |
|
6161 tfxApi->EnableEffects( EFalse ); |
|
6162 } |
|
6163 else if ( !aSuspend && !effectsEnabled && tfxApi ) |
|
6164 { |
|
6165 tfxApi->EnableEffects( ETrue ); |
|
6166 } |
|
6167 #endif// RD_UI_TRANSITION_EFFECTS_LIST |
|
6168 _AKNTRACE_FUNC_EXIT; |
|
6169 } |
|
6170 |
|
6171 |
|
6172 // --------------------------------------------------------------------------- |
|
6173 // Disables the single click functionality in the list. |
|
6174 // --------------------------------------------------------------------------- |
|
6175 // |
|
6176 EXPORT_C void CEikListBox::DisableSingleClick( TBool aDisabled ) |
|
6177 { |
|
6178 _AKNTRACE_FUNC_ENTER; |
|
6179 if ( aDisabled && iListBoxExt->iSingleClickEnabled ) |
|
6180 { |
|
6181 iListBoxExt->DisableSingleClick(); |
|
6182 } |
|
6183 _AKNTRACE_FUNC_EXIT; |
|
6184 } |
|
6185 |
|
6186 |
|
6187 // --------------------------------------------------------------------------- |
|
6188 // CEikListBox::DisableItemSpecificMenu |
|
6189 // --------------------------------------------------------------------------- |
|
6190 // |
|
6191 EXPORT_C void CEikListBox::DisableItemSpecificMenu() |
|
6192 { |
|
6193 if ( iListBoxExt ) |
|
6194 { |
|
6195 iListBoxExt->DisableItemSpecificMenu(); |
|
6196 } |
|
6197 } |
|
6198 |
|
6199 |
|
6200 void CEikListBox::ScrollView( const TInt aOffset, TBool aDrawNow ) |
|
6201 { |
|
6202 _AKNTRACE_FUNC_ENTER; |
|
6203 #ifdef _DEBUG |
|
6204 RDebug::Print( _L( "CEikListBox::ScrollView, aOffset = %d, aDrawNow = %d" ), aOffset, aDrawNow ); |
|
6205 #endif // _DEBUG |
|
6206 |
|
6207 if ( aOffset != 0 ) |
|
6208 { |
|
6209 TInt itemHeight = iView->ItemHeight(); |
|
6210 TInt viewHeight = iView->ViewRect().Size().iHeight; |
|
6211 TInt itemsInSingleLine = iListBoxExt->iItemsInSingleLine; |
|
6212 TInt oldListTopPos = ( iView->TopItemIndex() / itemsInSingleLine ) * itemHeight |
|
6213 - iView->ItemOffsetInPixels(); |
|
6214 TInt newListTopPos = oldListTopPos - aOffset; |
|
6215 |
|
6216 // calculate new top item index and offset |
|
6217 TInt newTopItemIndex = ( newListTopPos / itemHeight ) * itemsInSingleLine; |
|
6218 TInt newTopItemIndexBck = newTopItemIndex; |
|
6219 if ( newTopItemIndex >= Model()->NumberOfItems() ) |
|
6220 { |
|
6221 newTopItemIndexBck = Model()->NumberOfItems() - 1; |
|
6222 newTopItemIndex = Model()->NumberOfItems(); |
|
6223 } |
|
6224 |
|
6225 // feedback during flicking and panning |
|
6226 TInt newListBottomPos = newListTopPos + viewHeight; |
|
6227 |
|
6228 TInt newListLastItemPos = ( Model()->NumberOfItems()/itemsInSingleLine ) * itemHeight - newListTopPos; |
|
6229 if ( newTopItemIndex != iListBoxExt->iPrevTopItemIndex ) |
|
6230 { |
|
6231 iListBoxExt->iPrevTopItemIndex = newTopItemIndex; |
|
6232 if( iListBoxExt->FlickOrPanningOngoing() ) |
|
6233 { |
|
6234 if( ( newListBottomPos < iListBoxExt->ListBottomLimit() && newListTopPos > 0 ) || |
|
6235 ( newListBottomPos >= iListBoxExt->ListBottomLimit() ) || |
|
6236 ( newListTopPos <= 0 && newListTopPos + viewHeight >= 0 && newListLastItemPos > viewHeight ) ) |
|
6237 { |
|
6238 if ( CAknPhysics::EAknPhysicsActionFlicking == iListBoxExt->iPhysics->OngoingPhysicsAction() || |
|
6239 CAknPhysics::EAknPhysicsActionBouncing == iListBoxExt->iPhysics->OngoingPhysicsAction() ) |
|
6240 { |
|
6241 iListBoxExt->ImmediateFeedback( ETouchFeedbackSensitiveList, |
|
6242 TTouchFeedbackType( ETouchFeedbackVibra ), |
|
6243 TPointerEvent() ); |
|
6244 } |
|
6245 else if ( CAknPhysics::EAknPhysicsActionDragging == iListBoxExt->iPhysics->OngoingPhysicsAction() ) |
|
6246 { |
|
6247 iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType, |
|
6248 TTouchFeedbackType( ETouchFeedbackVibra | ETouchFeedbackAudio ), |
|
6249 TPointerEvent() ); |
|
6250 } |
|
6251 } |
|
6252 } |
|
6253 } |
|
6254 newTopItemIndex = newTopItemIndexBck; |
|
6255 if ( newTopItemIndex < 0 ) |
|
6256 { |
|
6257 newTopItemIndex = 0; |
|
6258 } |
|
6259 |
|
6260 // Top item index should always be the first item index in a row. |
|
6261 TInt notFirstInRow = newTopItemIndex % itemsInSingleLine; |
|
6262 |
|
6263 if ( notFirstInRow > 0 ) |
|
6264 { |
|
6265 newTopItemIndex -= notFirstInRow; |
|
6266 } |
|
6267 |
|
6268 TInt offset = ( newTopItemIndex / itemsInSingleLine ) * itemHeight - newListTopPos; |
|
6269 |
|
6270 iView->SetItemOffsetInPixels( offset ); |
|
6271 #ifdef _DEBUG |
|
6272 RDebug::Print( _L( "CEikListBox::ScrollView, newTopItemIndex = %d" ), newTopItemIndex ); |
|
6273 #endif // _DEBUG |
|
6274 iView->SetTopItemIndex( newTopItemIndex ); |
|
6275 } |
|
6276 if ( aDrawNow ) |
|
6277 { |
|
6278 TRect rect(Rect()); |
|
6279 |
|
6280 // list position changed |
|
6281 iListBoxExt->iBackgroundDrawingSuppressed = ETrue; |
|
6282 UpdateScrollBarThumbs(); |
|
6283 DrawNow(); |
|
6284 if (iSBFrame && iSBFrame->VerticalScrollBar() && !iSBFrame->VerticalScrollBar()->OwnsWindow()) |
|
6285 { |
|
6286 TRect srect( iSBFrame->VerticalScrollBar()->Rect() ); |
|
6287 if ( !srect.Intersects( rect )) |
|
6288 { |
|
6289 iSBFrame->DrawScrollBarsNow(); |
|
6290 } |
|
6291 } |
|
6292 iListBoxExt->iBackgroundDrawingSuppressed = EFalse; |
|
6293 } |
|
6294 _AKNTRACE_FUNC_EXIT; |
|
6295 } |
|
6296 |
|
6297 |
|
6298 // --------------------------------------------------------------------------- |
|
6299 // Handles pointer events if physics are enabled. |
|
6300 // --------------------------------------------------------------------------- |
|
6301 // |
|
6302 TBool CEikListBox::HandlePhysicsPointerEventL( const TPointerEvent& aPointerEvent ) |
|
6303 { |
|
6304 _AKNTRACE_FUNC_ENTER; |
|
6305 _AKNTRACE( "aPointerEvent.iType = %d", aPointerEvent.iType ); |
|
6306 if ( iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionBouncing ) |
|
6307 { |
|
6308 // Block scrolling events outside listbox area. Note that pointer |
|
6309 // event ignore must be done for the window-owning control or it |
|
6310 // doesn't have any effect! |
|
6311 CCoeControl* windowOwningControl = this; |
|
6312 |
|
6313 while ( windowOwningControl && !windowOwningControl->OwnsWindow() ) |
|
6314 { |
|
6315 windowOwningControl = windowOwningControl->Parent(); |
|
6316 } |
|
6317 |
|
6318 if ( windowOwningControl ) |
|
6319 { |
|
6320 windowOwningControl->IgnoreEventsUntilNextPointerUp(); |
|
6321 _AKNTRACE_FUNC_EXIT; |
|
6322 return ETrue; |
|
6323 } |
|
6324 } |
|
6325 |
|
6326 TBool blockEvent = EFalse; |
|
6327 |
|
6328 TBool allowDragEvent( ( iListBoxFlags & ELeftDownInViewRect ) && iSBFrame && !iListBoxExt->iScrollingDisabled ); |
|
6329 |
|
6330 |
|
6331 switch ( aPointerEvent.iType ) |
|
6332 { |
|
6333 case TPointerEvent::EButton1Down: |
|
6334 { |
|
6335 TInt tappedItemIndex = KErrNotFound; |
|
6336 iListBoxExt->iItemDraggingReported = EFalse; |
|
6337 |
|
6338 // If list is tapped while flicking then EEventItemClicked etc are not sent |
|
6339 if ( iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionFlicking ) |
|
6340 { |
|
6341 iListBoxExt->iClickEventsAllowed = EFalse; |
|
6342 if ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) |
|
6343 { |
|
6344 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
6345 } |
|
6346 |
|
6347 // Multiselection list tapped while flicking. |
|
6348 // Just move the highlight, pressed down highlight and |
|
6349 // item marking are ignored. |
|
6350 if ( iListBoxFlags & ES60StyleMultiselection ) |
|
6351 { |
|
6352 iListBoxExt->iIsDownOnItem = |
|
6353 iView->XYPosToItemIndex( aPointerEvent.iPosition, |
|
6354 tappedItemIndex ); |
|
6355 if ( iListBoxExt->iIsDownOnItem ) |
|
6356 { |
|
6357 iListBoxExt->iLastDownTappedItem = tappedItemIndex; |
|
6358 iListBoxExt->iMarkingDisabled = ETrue; |
|
6359 iListBoxFlags|=ELeftDownInViewRect; |
|
6360 blockEvent = ETrue; |
|
6361 } |
|
6362 } |
|
6363 } |
|
6364 else |
|
6365 { |
|
6366 iListBoxExt->iClickEventsAllowed = ETrue; |
|
6367 } |
|
6368 |
|
6369 if ( iView->XYPosToItemIndex( aPointerEvent.iPosition, tappedItemIndex ) ) |
|
6370 { |
|
6371 // Start highlight timer if needed |
|
6372 if ( tappedItemIndex != iView->CurrentItemIndex() || |
|
6373 iListBoxExt->iSingleClickEnabled ) |
|
6374 { |
|
6375 if ( !iListBoxExt->iSingleClickEnabled ) |
|
6376 { |
|
6377 iListBoxExt->StartHighlightTimer(); |
|
6378 } |
|
6379 else if ( !( iItemDrawer->Flags() & CListItemDrawer::EDisableMarquee ) ) |
|
6380 { |
|
6381 // Disable marquee |
|
6382 iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee ); |
|
6383 } |
|
6384 } |
|
6385 } |
|
6386 |
|
6387 iListBoxExt->iPhysics->StopPhysics(); |
|
6388 iListBoxExt->iPhysics->ResetFriction(); |
|
6389 iListBoxExt->iDragStartPosition = aPointerEvent.iPosition; |
|
6390 iListBoxExt->iLastPointerPos = aPointerEvent.iPosition; |
|
6391 iListBoxExt->iScrolling = EFalse; |
|
6392 iListBoxExt->InitPhysicsL(); |
|
6393 iListBoxExt->iStartTime.HomeTime(); |
|
6394 } |
|
6395 break; |
|
6396 case TPointerEvent::EButtonRepeat: // fall through |
|
6397 case TPointerEvent::EDrag: |
|
6398 { |
|
6399 if ( allowDragEvent ) |
|
6400 { |
|
6401 TPoint drag( iListBoxExt->iDragStartPosition - aPointerEvent.iPosition ); |
|
6402 |
|
6403 TInt currentItemIndex = iView->CurrentItemIndex(); |
|
6404 TInt touchedItemIndex( KErrNotFound ); |
|
6405 |
|
6406 if ( Abs( drag.iY ) > iListBoxExt->iPhysics->DragThreshold() && |
|
6407 !iListBoxExt->iScrolling ) |
|
6408 { |
|
6409 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6410 SuspendEffects( ETrue ); |
|
6411 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
6412 iListBoxExt->iScrolling = ETrue; |
|
6413 iListBoxExt->CancelHighlightTimer(); |
|
6414 |
|
6415 // Cancel long tap detecting |
|
6416 iListBoxExt->CancelLongTapL(); |
|
6417 // Remove highlight if single click enabled |
|
6418 if ( iListBoxExt->iSingleClickEnabled ) |
|
6419 { |
|
6420 iListBoxExt->EnableHighlight( EFalse ); |
|
6421 iListBoxExt->iLastDownTappedItem = KErrNotFound; |
|
6422 iView->SetItemIndex( 0 ); |
|
6423 } |
|
6424 |
|
6425 if ( iView->ItemIsVisible( currentItemIndex ) ) |
|
6426 { |
|
6427 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
6428 iView->DrawItem( currentItemIndex ); |
|
6429 } |
|
6430 |
|
6431 ReportListBoxEventL( MEikListBoxObserver::EEventPanningStarted ); |
|
6432 } |
|
6433 else if ( !iListBoxExt->iScrolling && |
|
6434 iView->XYPosToItemIndex( aPointerEvent.iPosition, touchedItemIndex ) ) |
|
6435 { |
|
6436 // Don't send the dragging actioned event if the |
|
6437 // highlight timer hasn't yet completed as in that case |
|
6438 // the current item index isn't updated yet. |
|
6439 if ( currentItemIndex != touchedItemIndex && |
|
6440 !iListBoxExt->iItemDraggingReported && |
|
6441 !iListBoxExt->HighlightTimerActive() ) |
|
6442 { |
|
6443 iListBoxExt->iItemDraggingReported = ETrue; |
|
6444 ReportListBoxEventL( MEikListBoxObserver::EEventItemDraggingActioned ); |
|
6445 } |
|
6446 } |
|
6447 if ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState |
|
6448 && !iView->ItemIsVisible( currentItemIndex ) ) |
|
6449 { |
|
6450 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
6451 } |
|
6452 |
|
6453 if ( iListBoxExt->iScrolling ) |
|
6454 { |
|
6455 iListBoxExt->iPhysics->RegisterPanningPosition( |
|
6456 TPoint( 0, iListBoxExt->iLastPointerPos.iY - aPointerEvent.iPosition.iY ) ); |
|
6457 |
|
6458 #ifdef _DEBUG |
|
6459 RDebug::Print( _L( "CEikListBox::HandlePhysicsPointerEventL, newViewPosition.iX = %d, iY = %d" ), iListBoxExt->iViewPosition.iX, iListBoxExt->iViewPosition.iY ); |
|
6460 RDebug::Print( _L( "CEikListBox::HandlePhysicsPointerEventL, iListBoxExt->iLastPointerPos.iY = %d" ), iListBoxExt->iLastPointerPos.iY ); |
|
6461 RDebug::Print( _L( "CEikListBox::HandlePhysicsPointerEventL, aPointerEvent.iPosition.iY = %d" ), aPointerEvent.iPosition.iY ); |
|
6462 #endif // _DEBUG |
|
6463 |
|
6464 blockEvent = ETrue; |
|
6465 } |
|
6466 |
|
6467 iListBoxExt->iLastPointerPos = aPointerEvent.iPosition; |
|
6468 } |
|
6469 } |
|
6470 break; |
|
6471 |
|
6472 case TPointerEvent::EButton1Up: |
|
6473 { |
|
6474 if ( iListBoxFlags & ES60StyleMultiselection |
|
6475 && iListBoxExt->iMarkingDisabled ) |
|
6476 { |
|
6477 // Allow marking again on next up event. |
|
6478 iListBoxExt->iMarkingDisabled = EFalse; |
|
6479 blockEvent = ETrue; |
|
6480 } |
|
6481 |
|
6482 // update selected item in case highlight timer is still running |
|
6483 if ( iListBoxExt->HighlightTimerActive() ) |
|
6484 { |
|
6485 // Must cancel highlight timer directly instead of using |
|
6486 // CListBoxExt::CancelHighlightTimer(), because it will |
|
6487 // also clear the flags used in the highlight timer |
|
6488 // callback function. |
|
6489 iListBoxExt->iHighlightTimer->Cancel(); |
|
6490 CListBoxExt::HighlightTimerCallback( iListBoxExt ); |
|
6491 } |
|
6492 |
|
6493 TPoint drag( iListBoxExt->iDragStartPosition - aPointerEvent.iPosition ); |
|
6494 |
|
6495 iListBoxExt->LongTapPointerEventL( aPointerEvent ); |
|
6496 |
|
6497 if ( allowDragEvent && |
|
6498 iListBoxExt->iPhysics->StartPhysics( drag, iListBoxExt->iStartTime ) ) |
|
6499 { |
|
6500 iListBoxExt->CancelLongTapL(); |
|
6501 |
|
6502 if ( !iListBoxExt->iScrolling ) |
|
6503 { |
|
6504 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6505 SuspendEffects( ETrue ); |
|
6506 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
6507 iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); |
|
6508 iView->DrawItem( iView->CurrentItemIndex() ); |
|
6509 iListBoxExt->iScrolling = ETrue; |
|
6510 } |
|
6511 else |
|
6512 { |
|
6513 ReportListBoxEventL( MEikListBoxObserver::EEventPanningStopped ); |
|
6514 } |
|
6515 |
|
6516 blockEvent = ETrue; |
|
6517 |
|
6518 // Clearing ELeftDownInViewRect should be done by rest code in |
|
6519 // CEikListBox::HandlePointerEventL, but since the event is |
|
6520 // blocked, do it here |
|
6521 iListBoxFlags&=(~ELeftDownInViewRect); |
|
6522 |
|
6523 ReportListBoxEventL( MEikListBoxObserver::EEventFlickStarted ); |
|
6524 } |
|
6525 else |
|
6526 { |
|
6527 iListBoxExt->iScrolling = EFalse; |
|
6528 } |
|
6529 |
|
6530 if ( iListBoxExt->iSingleClickEnabled |
|
6531 && iListBoxExt->iLongTappedItem == KErrNotFound ) |
|
6532 { |
|
6533 iListBoxExt->EnableHighlight( EFalse ); |
|
6534 TInt itemIndex( 0 ); |
|
6535 if ( !iView->XYPosToItemIndex( |
|
6536 aPointerEvent.iPosition, itemIndex ) ) |
|
6537 { |
|
6538 iListBoxExt->iLastDownTappedItem = KErrNotFound; |
|
6539 } |
|
6540 } |
|
6541 } |
|
6542 iListBoxExt->iIsDownOnItem = EFalse; |
|
6543 break; |
|
6544 |
|
6545 default: |
|
6546 break; |
|
6547 } |
|
6548 |
|
6549 iView->SetScrolling( iListBoxExt->iScrolling ); |
|
6550 _AKNTRACE_FUNC_EXIT; |
|
6551 return blockEvent; |
|
6552 } |
|
6553 |
|
6554 |
|
6555 // --------------------------------------------------------------------------- |
|
6556 // Draws the highlight to the current item. |
|
6557 // --------------------------------------------------------------------------- |
|
6558 // |
|
6559 void CEikListBox::UpdateHighlightL( TInt aItemIndex ) |
|
6560 { |
|
6561 _AKNTRACE_FUNC_ENTER; |
|
6562 TInt oldCurrentItemIndex = iView->CurrentItemIndex(); |
|
6563 |
|
6564 if ( iListBoxExt->iReportDelayedPenDown && !iListBoxExt->iScrolling ) |
|
6565 { |
|
6566 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6567 if ( aItemIndex != oldCurrentItemIndex ) |
|
6568 { |
|
6569 MAknListBoxTfxInternal* transApi = |
|
6570 CAknListLoader::TfxApiInternal( iView->iGc ); |
|
6571 if ( transApi && !transApi->EffectsDisabled() ) |
|
6572 { |
|
6573 transApi->SetMoveType( MAknListBoxTfxInternal::EListTap ); |
|
6574 } |
|
6575 } |
|
6576 #endif |
|
6577 iView->SetItemIndex( aItemIndex ); |
|
6578 ReportListBoxEventL( |
|
6579 MEikListBoxObserver::EEventPenDownOnItem ); |
|
6580 |
|
6581 // The long tap animation should start after the highlight has |
|
6582 // been made visible. |
|
6583 iListBoxExt->LongTapPointerEventL( |
|
6584 iListBoxExt->iDelayedPointerDownEvent ); |
|
6585 } |
|
6586 |
|
6587 if ( iListBoxExt->iDelayedMultiselection ) |
|
6588 { |
|
6589 iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); |
|
6590 } |
|
6591 |
|
6592 iView->SetItemIndex( aItemIndex ); |
|
6593 |
|
6594 if ( iListBoxExt->iMarkableListMarking ) |
|
6595 { |
|
6596 if ( iListBoxExt->iMarkableListShiftKeyPressed ) |
|
6597 { |
|
6598 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6599 iListBoxExt->iAnchor = oldCurrentItemIndex; |
|
6600 iListBoxExt->iSelect = |
|
6601 !iView->ItemIsSelected( iView->CurrentItemIndex() ); |
|
6602 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
6603 |
|
6604 iView->SetAnchor( oldCurrentItemIndex ); |
|
6605 iView->UpdateSelectionL( CListBoxView::EChangeMarkMode ); |
|
6606 iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); |
|
6607 iView->UpdateSelectionL( CListBoxView::EPenMultiselection ); |
|
6608 } |
|
6609 else |
|
6610 { |
|
6611 iView->SetAnchor( aItemIndex - 1 ); |
|
6612 |
|
6613 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
6614 iListBoxExt->iAnchor = aItemIndex - 1; |
|
6615 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
6616 } |
|
6617 |
|
6618 iListBoxExt->iMarkableListMarking = EFalse; |
|
6619 } |
|
6620 |
|
6621 iView->DrawItem( oldCurrentItemIndex ); |
|
6622 iView->DrawItem( aItemIndex ); |
|
6623 |
|
6624 if ( iListBoxExt->iDelayedMultiselection ) |
|
6625 { |
|
6626 iListBoxFlags |= EStateChanged; |
|
6627 Buffer()->iPressedIndex = aItemIndex; |
|
6628 } |
|
6629 |
|
6630 ReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6631 _AKNTRACE_FUNC_EXIT; |
|
6632 } |
|
6633 |
|
6634 |
|
6635 // --------------------------------------------------------------------------- |
|
6636 // Sets this control as visible or invisible. |
|
6637 // --------------------------------------------------------------------------- |
|
6638 // |
|
6639 EXPORT_C void CEikListBox::MakeVisible( TBool aVisible ) |
|
6640 { |
|
6641 CEikBorderedControl::MakeVisible( aVisible ); |
|
6642 if ( iListBoxExt ) |
|
6643 { |
|
6644 if ( !aVisible ) |
|
6645 { |
|
6646 iListBoxExt->EnableHighlight( EFalse ); |
|
6647 } |
|
6648 else |
|
6649 { |
|
6650 iListBoxExt->ReportCollectionChangedEvent(); |
|
6651 } |
|
6652 } |
|
6653 } |
|
6654 |
|
6655 // |
|
6656 // class CEikSnakingListBox |
|
6657 // |
|
6658 |
|
6659 EXPORT_C CEikSnakingListBox::CEikSnakingListBox() |
|
6660 { |
|
6661 AKNTASHOOK_ADD( this, "CEikSnakingListBox" ); |
|
6662 } |
|
6663 |
|
6664 EXPORT_C CEikSnakingListBox::~CEikSnakingListBox() |
|
6665 { |
|
6666 AKNTASHOOK_REMOVE(); |
|
6667 } |
|
6668 |
|
6669 EXPORT_C CListBoxView* CEikSnakingListBox::MakeViewClassInstanceL() |
|
6670 { |
|
6671 return (new(ELeave) CSnakingListBoxView); |
|
6672 } |
|
6673 |
|
6674 EXPORT_C TInt CEikSnakingListBox::ColumnWidth() const |
|
6675 { |
|
6676 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
6677 return ((CSnakingListBoxView*)iView)->ColumnWidth(); |
|
6678 } |
|
6679 |
|
6680 EXPORT_C void CEikSnakingListBox::SetColumnWidth(TInt aColumnWidth) |
|
6681 { |
|
6682 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
6683 ((CSnakingListBoxView*)iView)->SetColumnWidth(aColumnWidth); |
|
6684 } |
|
6685 |
|
6686 EXPORT_C void CEikSnakingListBox::HandleLeftArrowKeyL(CListBoxView::TSelectionMode aSelectionMode) |
|
6687 { |
|
6688 iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, aSelectionMode); |
|
6689 ClearMatchBuffer(); |
|
6690 } |
|
6691 |
|
6692 EXPORT_C void CEikSnakingListBox::HandleRightArrowKeyL(CListBoxView::TSelectionMode aSelectionMode) |
|
6693 { |
|
6694 iView->MoveCursorL(CListBoxView::ECursorNextColumn, aSelectionMode); |
|
6695 ClearMatchBuffer(); |
|
6696 } |
|
6697 |
|
6698 EXPORT_C TInt CEikSnakingListBox::HorizontalNudgeValue() const |
|
6699 { |
|
6700 return 1; // scroll horizontal by one column when the left/right scroll arrows (i.e. the nudge buttons) are tapped |
|
6701 } |
|
6702 |
|
6703 EXPORT_C TInt CEikSnakingListBox::HorizScrollGranularityInPixels() const |
|
6704 { |
|
6705 return ColumnWidth(); // horiz scrollbar model set in columns for snaking list box |
|
6706 } |
|
6707 |
|
6708 EXPORT_C void CEikSnakingListBox::SetTopItemIndex(TInt aItemIndex) const |
|
6709 { |
|
6710 __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView)); |
|
6711 iView->SetTopItemIndex(aItemIndex); |
|
6712 } |
|
6713 |
|
6714 EXPORT_C void CEikSnakingListBox::HandleViewRectSizeChangeL() |
|
6715 { |
|
6716 _AKNTRACE_FUNC_ENTER; |
|
6717 iView->CalcBottomItemIndex(); |
|
6718 TInt oldTopItemIndex = TopItemIndex(); |
|
6719 TInt newTopItemIndex = TopItemIndex(); |
|
6720 TInt currentItemIndex = CurrentItemIndex(); |
|
6721 TInt numOfItemsPerColumn = 0; |
|
6722 UpdateScrollBarsL(); |
|
6723 numOfItemsPerColumn = iView->ViewRect().Height() / iItemHeight; |
|
6724 numOfItemsPerColumn = Max(1, numOfItemsPerColumn); |
|
6725 if (currentItemIndex != oldTopItemIndex) |
|
6726 { |
|
6727 TInt colIndexOfTargetItem = currentItemIndex / numOfItemsPerColumn; |
|
6728 TInt numOfColsThatFitInViewRect = iView->VisibleWidth(iView->ViewRect()); |
|
6729 TInt adjustment = newTopItemIndex % numOfItemsPerColumn; |
|
6730 if (adjustment != 0) |
|
6731 // adjust newTopItemIndex till it refers to the index of an item at the top of a column |
|
6732 newTopItemIndex -= adjustment; |
|
6733 TInt newBottomItemIndex = newTopItemIndex + (numOfColsThatFitInViewRect * numOfItemsPerColumn) - 1; |
|
6734 if (currentItemIndex < newTopItemIndex) |
|
6735 newTopItemIndex = colIndexOfTargetItem * numOfItemsPerColumn; |
|
6736 else if (currentItemIndex > newBottomItemIndex) |
|
6737 { |
|
6738 TInt colIndexOfNewBottomItem = colIndexOfTargetItem; |
|
6739 TInt colIndexOfNewTopItem = colIndexOfNewBottomItem - (numOfColsThatFitInViewRect - 1); |
|
6740 newTopItemIndex = colIndexOfNewTopItem * numOfItemsPerColumn; |
|
6741 } |
|
6742 } |
|
6743 else if ((newTopItemIndex != 0) && (numOfItemsPerColumn != 0)) |
|
6744 { |
|
6745 TInt adjustment = newTopItemIndex % numOfItemsPerColumn; |
|
6746 if (adjustment != 0) |
|
6747 // adjust newTopItemIndex till it refers to the index of an item at the top of a column |
|
6748 newTopItemIndex -= adjustment; |
|
6749 } |
|
6750 SetTopItemIndex(newTopItemIndex); |
|
6751 iView->CalcDataWidth(); |
|
6752 UpdateScrollBarsL(); |
|
6753 iView->CalcBottomItemIndex(); |
|
6754 _AKNTRACE_FUNC_EXIT; |
|
6755 } |
|
6756 |
|
6757 EXPORT_C void CEikSnakingListBox::SizeChanged() |
|
6758 { |
|
6759 TRect clientRect = iBorder.InnerRect(Rect()); |
|
6760 SetViewRectFromClientRect(clientRect); |
|
6761 TRAP_IGNORE(HandleViewRectSizeChangeL()); |
|
6762 } |
|
6763 |
|
6764 EXPORT_C void CEikSnakingListBox::AdjustTopItemIndex() const |
|
6765 { |
|
6766 _AKNTRACE_FUNC_ENTER; |
|
6767 // assumes we know # of items in the model |
|
6768 TInt numOfItemsPerCol = iView->ViewRect().Height() / iItemHeight; |
|
6769 numOfItemsPerCol = Max(1, numOfItemsPerCol); |
|
6770 TInt numOfVisCols = iView->VisibleWidth(iView->ViewRect()); |
|
6771 TInt numOfItems = iModel->NumberOfItems(); |
|
6772 TInt colIndexOfRightmostCol = numOfItems / numOfItemsPerCol; |
|
6773 TInt maxTopItemIndex = Max (0, (colIndexOfRightmostCol - (numOfVisCols - 1)) * numOfItemsPerCol); |
|
6774 if (iView->TopItemIndex() > maxTopItemIndex) |
|
6775 SetTopItemIndex(maxTopItemIndex); |
|
6776 _AKNTRACE_FUNC_EXIT; |
|
6777 } |
|
6778 |
|
6779 EXPORT_C void CEikSnakingListBox::HandleDragEventL(TPoint aPointerPos) |
|
6780 { |
|
6781 _AKNTRACE_FUNC_ENTER; |
|
6782 if (!(iListBoxFlags & ELeftDownInViewRect)) |
|
6783 { |
|
6784 _AKNTRACE_FUNC_EXIT; |
|
6785 return; |
|
6786 } |
|
6787 TRect ignoreDragRect(TPoint(aPointerPos.iX-20, aPointerPos.iY-20), TPoint(aPointerPos.iX+20, aPointerPos.iY+20)); |
|
6788 TRect viewRect(iView->ViewRect()); |
|
6789 TInt itemIndex; |
|
6790 TBool pointerIsOverAnItem = iView->XYPosToItemIndex(aPointerPos, itemIndex); |
|
6791 // SERIES60 LAF |
|
6792 #if 1 |
|
6793 CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection; |
|
6794 #else |
|
6795 CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection; |
|
6796 #endif |
|
6797 // END OF SERIES60 LAF |
|
6798 TInt oldCurrentItemIndex = iView->CurrentItemIndex(); |
|
6799 TRect currentItemRect(iView->ItemPos(oldCurrentItemIndex), iView->ItemSize(oldCurrentItemIndex)); |
|
6800 if (pointerIsOverAnItem) |
|
6801 { |
|
6802 // drag event occurred within the listbox |
|
6803 iView->SetCurrentItemIndex(itemIndex); |
|
6804 if (itemIndex != oldCurrentItemIndex) |
|
6805 { |
|
6806 iView->SetCurrentItemIndex(itemIndex); |
|
6807 iView->DrawItem(oldCurrentItemIndex); |
|
6808 iView->UpdateSelectionL(selectionMode); |
|
6809 iView->DrawItem(itemIndex); |
|
6810 } |
|
6811 } |
|
6812 else if ((aPointerPos.iX < viewRect.iTl.iX) || (aPointerPos.iX > viewRect.iBr.iX)) |
|
6813 { |
|
6814 // drag event occurred outside the listbox's viewRect |
|
6815 if (aPointerPos.iX < viewRect.iTl.iX) |
|
6816 iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode); |
|
6817 else if (aPointerPos.iX > viewRect.iBr.iX) |
|
6818 iView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode); |
|
6819 MoveToNextOrPreviousItemL(aPointerPos); |
|
6820 UpdateScrollBarThumbs(); |
|
6821 Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect); |
|
6822 // Window().RequestPointerRepeatEvent(ListBoxLaf()->LBxPointerRepeatInterval(), ignoreDragRect); |
|
6823 } |
|
6824 else |
|
6825 { |
|
6826 // find item nearest to the pointer pos and make that the current item |
|
6827 if (viewRect.Contains(aPointerPos)) |
|
6828 { |
|
6829 } |
|
6830 else |
|
6831 { |
|
6832 if (aPointerPos.iX > currentItemRect.iBr.iX) |
|
6833 iView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode); |
|
6834 else if (aPointerPos.iX < currentItemRect.iTl.iX) |
|
6835 iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode); |
|
6836 MoveToNextOrPreviousItemL(aPointerPos); |
|
6837 UpdateScrollBarThumbs(); |
|
6838 Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect); |
|
6839 // Window().RequestPointerRepeatEvent(ListBoxLaf()->LBxPointerRepeatInterval(), ignoreDragRect); |
|
6840 } |
|
6841 } |
|
6842 if (iView->CurrentItemIndex() != oldCurrentItemIndex) |
|
6843 { |
|
6844 iListBoxFlags |= EStateChanged; |
|
6845 if (IsMatchBuffer()) |
|
6846 { |
|
6847 ClearMatchBuffer(); |
|
6848 DrawMatcherCursor(); |
|
6849 } |
|
6850 } |
|
6851 } |
|
6852 |
|
6853 EXPORT_C void CEikSnakingListBox::MoveToNextOrPreviousItemL(TPoint aPointerPos) |
|
6854 { |
|
6855 // AVKON LAF |
|
6856 #if 1 |
|
6857 CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection; |
|
6858 #else |
|
6859 CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection; |
|
6860 #endif |
|
6861 // END OF AVKON LAF |
|
6862 TInt cix = iView->CurrentItemIndex(); |
|
6863 TRect currentItemRect(iView->ItemPos(cix), iView->ItemSize(cix)); |
|
6864 TInt numOfRows = ((CSnakingListBoxView*)iView)->NumberOfItemsPerColumn(); |
|
6865 TBool currItemIsInLastRow = ((cix % numOfRows) == (numOfRows-1)); |
|
6866 TBool currItemIsLastItem = (cix == (iModel->NumberOfItems()-1)); |
|
6867 TBool currItemIsInFirstRow = ((cix % numOfRows) == 0); |
|
6868 if ((aPointerPos.iY > currentItemRect.iBr.iY) && (! (currItemIsInLastRow || currItemIsLastItem))) |
|
6869 iView->MoveCursorL(CListBoxView::ECursorNextItem, selectionMode); |
|
6870 else if ((aPointerPos.iY < currentItemRect.iTl.iY) && (! currItemIsInFirstRow)) |
|
6871 iView->MoveCursorL(CListBoxView::ECursorPreviousItem, selectionMode); |
|
6872 _AKNTRACE_FUNC_EXIT; |
|
6873 } |
|
6874 |
|
6875 EXPORT_C void CEikSnakingListBox::RestoreClientRectFromViewRect(TRect& aClientRect) const |
|
6876 { |
|
6877 aClientRect=iView->ViewRect(); |
|
6878 aClientRect.SetRect(aClientRect.iTl.iX - ListBoxMargins().iLeft, aClientRect.iTl.iY - ListBoxMargins().iTop, |
|
6879 aClientRect.iBr.iX + ListBoxMargins().iRight, aClientRect.iBr.iY + ListBoxMargins().iBottom); |
|
6880 if (!ViewRectHeightAdjustment()) |
|
6881 return; |
|
6882 aClientRect.iBr.iY += ViewRectHeightAdjustment(); |
|
6883 } |
|
6884 |
|
6885 EXPORT_C TInt CEikSnakingListBox::AdjustRectHeightToWholeNumberOfItems(TRect& aRect) const |
|
6886 { |
|
6887 TInt remainder = aRect.Height() % iItemHeight; |
|
6888 if (remainder != 0) |
|
6889 aRect.iBr.iY -= remainder; |
|
6890 return remainder; |
|
6891 } |
|
6892 |
|
6893 /** |
|
6894 * Gets the list of logical colors employed in the drawing of the control, |
|
6895 * paired with an explanation of how they are used. Appends the list to aColorUseList. |
|
6896 * |
|
6897 * @since ER5U |
|
6898 */ |
|
6899 EXPORT_C void CEikSnakingListBox::GetColorUseListL(CArrayFix<TCoeColorUse>& /*aColorUseList*/) const |
|
6900 { |
|
6901 } |
|
6902 |
|
6903 /** |
|
6904 * Handles a change to the control's resources of type aType |
|
6905 * which are shared across the environment, e.g. colors or fonts. |
|
6906 * |
|
6907 * @since ER5U |
|
6908 */ |
|
6909 EXPORT_C void CEikSnakingListBox::HandleResourceChange(TInt aType) |
|
6910 { |
|
6911 CCoeControl::HandleResourceChange(aType); |
|
6912 } |
|
6913 |
|
6914 EXPORT_C void CEikSnakingListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
6915 { |
|
6916 CEikListBox::HandlePointerEventL(aPointerEvent); |
|
6917 } |
|
6918 |
|
6919 EXPORT_C void* CEikSnakingListBox::ExtensionInterface( TUid /*aInterface*/ ) |
|
6920 { |
|
6921 return NULL; |
|
6922 } |
|
6923 |
|
6924 EXPORT_C void CEikSnakingListBox::Reserved_1() |
|
6925 {} |
|
6926 |
|
6927 EXPORT_C void CEikSnakingListBox::Reserved_2() |
|
6928 {} |
|
6929 |
|
6930 EXPORT_C void CEikSnakingListBox::CEikListBox_Reserved() |
|
6931 {} |