|
1 /* |
|
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <eikfrlb.h> |
|
20 #include <barsread.h> |
|
21 #include <gulicon.h> |
|
22 #include <AknUtils.h> |
|
23 #include <AknsControlContext.h> |
|
24 #include <AknBidiTextUtils.h> |
|
25 #include <aknlists.h> |
|
26 #include <aknlayoutscalable_avkon.cdl.h> |
|
27 |
|
28 #include <AknTasHook.h> |
|
29 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
30 #include <aknlistloadertfx.h> |
|
31 #include <aknlistboxtfxinternal.h> |
|
32 #include <aknlistboxtfx.h> |
|
33 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
34 |
|
35 #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS |
|
36 #include <akntransitionutils.h> |
|
37 #endif |
|
38 |
|
39 #include "akntrace.h" |
|
40 |
|
41 _LIT(KMarkReplacementString, "%S"); |
|
42 // |
|
43 // CFormattedCellListBoxItemDrawer |
|
44 // |
|
45 |
|
46 EXPORT_C |
|
47 CFormattedCellListBoxItemDrawer::CFormattedCellListBoxItemDrawer(MTextListBoxModel* aTextListBoxModel, |
|
48 const CFont* aFont, |
|
49 CFormattedCellListBoxData* aFormattedCellData) |
|
50 : CTextListItemDrawer(aTextListBoxModel, aFont) |
|
51 { |
|
52 _AKNTRACE_FUNC_ENTER; |
|
53 SetData(aFormattedCellData); |
|
54 _AKNTRACE_FUNC_EXIT; |
|
55 } |
|
56 |
|
57 EXPORT_C |
|
58 CFormattedCellListBoxItemDrawer::~CFormattedCellListBoxItemDrawer() |
|
59 { |
|
60 _AKNTRACE_FUNC_ENTER; |
|
61 delete iPropertyArray; |
|
62 _AKNTRACE_FUNC_EXIT; |
|
63 } |
|
64 |
|
65 EXPORT_C CFormattedCellListBoxData* |
|
66 CFormattedCellListBoxItemDrawer::FormattedCellData() const |
|
67 { |
|
68 return STATIC_CAST(CFormattedCellListBoxData*,iData); |
|
69 } |
|
70 EXPORT_C CFormattedCellListBoxData* |
|
71 CFormattedCellListBoxItemDrawer::ColumnData() const |
|
72 { |
|
73 return STATIC_CAST(CFormattedCellListBoxData*,iData); |
|
74 } |
|
75 |
|
76 |
|
77 EXPORT_C void CFormattedCellListBoxView::DrawEmptyList(const TRect &aClientRect) const |
|
78 { |
|
79 _AKNTRACE_FUNC_ENTER; |
|
80 if ( RedrawDisabled() || !IsVisible() ) |
|
81 { |
|
82 _AKNTRACE( "[%s][%s] RedrawDisabled or view invisible","CFormattedCellListBoxView",__FUNCTION__); |
|
83 _AKNTRACE_FUNC_EXIT; |
|
84 return; |
|
85 } |
|
86 |
|
87 #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS |
|
88 CWindowGc* systemGc = ( CWindowGc* )CAknTransitionUtils::GetData( ( TInt )this ); |
|
89 AknDrawWithSkins::DrawEmptyList( aClientRect, |
|
90 systemGc ? *systemGc : *iGc, |
|
91 *EmptyListText(), |
|
92 ((CFormattedCellListBoxItemDrawer*)ItemDrawer())->FormattedCellData()->Control() ); |
|
93 #else |
|
94 AknDrawWithSkins::DrawEmptyList( aClientRect, |
|
95 *iGc, |
|
96 *EmptyListText(), |
|
97 ((CFormattedCellListBoxItemDrawer*)ItemDrawer())->FormattedCellData()->Control() ); |
|
98 #endif |
|
99 _AKNTRACE_FUNC_EXIT; |
|
100 } |
|
101 |
|
102 EXPORT_C void CFormattedCellListBoxView::CalcBottomItemIndex() |
|
103 { |
|
104 CListBoxView::CalcBottomItemIndex(); |
|
105 |
|
106 CFormattedCellListBoxItemDrawer* itemDrawer = |
|
107 STATIC_CAST(CFormattedCellListBoxItemDrawer*,iItemDrawer); |
|
108 if (itemDrawer && itemDrawer->FormattedCellData() && |
|
109 itemDrawer->FormattedCellData()->Control()) |
|
110 { |
|
111 CEikFormattedCellListBox* listbox = STATIC_CAST(CEikFormattedCellListBox*, |
|
112 itemDrawer->FormattedCellData()->Control()); |
|
113 listbox->SetIconSizes(); |
|
114 } |
|
115 |
|
116 // The next piece of code removes filtering from find box when |
|
117 // new list items are added. |
|
118 if (Flags() & CListBoxView::EItemCountModified) |
|
119 { |
|
120 CAknFilteredTextListBoxModel *model = STATIC_CAST(CAknFilteredTextListBoxModel*,iModel); |
|
121 CAknListBoxFilterItems *filter = model ? model->Filter() : 0; |
|
122 if (filter) |
|
123 { |
|
124 TRAP_IGNORE(filter->ResetFilteringL()); |
|
125 } |
|
126 } |
|
127 } |
|
128 |
|
129 EXPORT_C TAny* CFormattedCellListBoxView::Reserved_1() |
|
130 { |
|
131 return NULL; |
|
132 } |
|
133 |
|
134 EXPORT_C void |
|
135 CFormattedCellListBoxItemDrawer::DrawEmptyItem( TInt /*aItemIndex*/, |
|
136 TPoint aItemRectPos, |
|
137 TBool /*aViewIsDimmed*/ ) const |
|
138 { |
|
139 _AKNTRACE_FUNC_ENTER; |
|
140 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
141 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
142 if ( transApi ) |
|
143 { |
|
144 transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); |
|
145 } |
|
146 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
147 TRect r( aItemRectPos, iItemCellSize ); |
|
148 CCoeControl* control = FormattedCellData()->Control(); |
|
149 |
|
150 const MCoeControlBackground* backgroundDrawer = control->FindBackground(); |
|
151 |
|
152 if ( control ) |
|
153 { |
|
154 MAknsControlContext *cc = AknsDrawUtils::ControlContext( control ); |
|
155 |
|
156 if ( !cc ) |
|
157 { |
|
158 cc = FormattedCellData()->SkinBackgroundContext(); |
|
159 } |
|
160 |
|
161 if ( backgroundDrawer ) |
|
162 { |
|
163 backgroundDrawer->Draw( *iGc, *control, r ); |
|
164 } |
|
165 else if ( CAknEnv::Static()->TransparencyEnabled() ) |
|
166 { |
|
167 AknsDrawUtils::Background( AknsUtils::SkinInstance(), cc, control, *iGc, r, |
|
168 KAknsDrawParamNoClearUnderImage ); |
|
169 } |
|
170 else |
|
171 { |
|
172 AknsDrawUtils::Background( AknsUtils::SkinInstance(), cc, control, *iGc, r, |
|
173 KAknsDrawParamNoClearUnderImage | |
|
174 KAknsDrawParamBottomLevelRGBOnly ); |
|
175 } |
|
176 } |
|
177 else |
|
178 { |
|
179 iGc->Clear( r ); |
|
180 } |
|
181 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
182 if ( transApi ) |
|
183 { |
|
184 transApi->StopDrawing(); |
|
185 } |
|
186 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
187 _AKNTRACE_FUNC_EXIT; |
|
188 } |
|
189 |
|
190 struct TLafTable; |
|
191 const TLafTable &BgListPaneTable(); |
|
192 |
|
193 EXPORT_C |
|
194 void CFormattedCellListBoxItemDrawer::DrawItemText( TInt aItemIndex, |
|
195 const TRect& aItemTextRect, |
|
196 TBool aItemIsCurrent, |
|
197 TBool aViewIsEmphasized, |
|
198 TBool aItemIsSelected) const |
|
199 { |
|
200 _AKNTRACE_FUNC_ENTER; |
|
201 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
202 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
203 if ( transApi ) |
|
204 { |
|
205 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); |
|
206 } |
|
207 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
208 iGc->SetPenColor(iTextColor); |
|
209 iGc->SetBrushColor(iBackColor); |
|
210 |
|
211 TPtrC temp=iModel->ItemText(aItemIndex); |
|
212 |
|
213 SetupGc(aItemIndex); |
|
214 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
215 if ( transApi ) |
|
216 { |
|
217 transApi->StopDrawing(); |
|
218 } |
|
219 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
220 |
|
221 TBool removeicon = (!aItemIsSelected && !ItemMarkReverse()) || (aItemIsSelected && ItemMarkReverse()); |
|
222 |
|
223 CFormattedCellListBoxData::TColors colors; |
|
224 colors.iText=iTextColor; |
|
225 colors.iBack=iBackColor; |
|
226 colors.iHighlightedText=iHighlightedTextColor; |
|
227 colors.iHighlightedBack=iHighlightedBackColor; |
|
228 |
|
229 DrawBackgroundAndSeparatorLines( aItemTextRect ); |
|
230 |
|
231 TBool highlightShown = ETrue; |
|
232 |
|
233 if (FormattedCellData()->RespectFocus() && !aViewIsEmphasized) |
|
234 { |
|
235 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
236 if ( transApi ) |
|
237 { |
|
238 transApi->Remove( MAknListBoxTfxInternal::EListHighlight ); |
|
239 } |
|
240 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
241 |
|
242 highlightShown = EFalse; |
|
243 } |
|
244 |
|
245 if (FormattedCellData()->IsMarqueeOn() && FormattedCellData()->CurrentMarqueeItemIndex() != aItemIndex && aItemIsCurrent) |
|
246 { |
|
247 FormattedCellData()->ResetMarquee(); |
|
248 FormattedCellData()->SetCurrentMarqueeItemIndex(aItemIndex); |
|
249 } |
|
250 |
|
251 if ( aItemIsCurrent ) |
|
252 { |
|
253 FormattedCellData()->SetCurrentItemIndex( aItemIndex ); |
|
254 } |
|
255 |
|
256 FormattedCellData()->SetCurrentlyDrawnItemIndex( aItemIndex ); |
|
257 |
|
258 // drawing with mark icon |
|
259 if ( Flags() & EDrawMarkSelection && ItemMarkPosition() != -1 && removeicon) |
|
260 { |
|
261 // Try to allocate buffer dynamically. If out of memory, just use normal drawing |
|
262 // without mark icon. |
|
263 // (+2 is for the possible 2 additional column separators) |
|
264 TPtrC repl; |
|
265 repl.Set( ItemMarkReplacement() ); |
|
266 TInt size = temp.Length() + repl.Length() + 2; |
|
267 //TBufC<KMaxTotalDataLength> target(KNullDesC); |
|
268 HBufC* buffer = HBufC::New( size ); |
|
269 |
|
270 if( buffer ) |
|
271 { |
|
272 TPtr des = buffer->Des(); |
|
273 TInt markPos = ItemMarkPosition(); // -1 if not set |
|
274 TInt startPos(0); |
|
275 TInt endPos(0); |
|
276 |
|
277 while( endPos < temp.Length() && markPos >= 0 ) |
|
278 { |
|
279 if( temp[endPos] == '\t' ) |
|
280 { |
|
281 markPos--; |
|
282 if( markPos == 0 ) |
|
283 { |
|
284 startPos = endPos + 1; // +1 for column separator |
|
285 } |
|
286 } |
|
287 endPos++; |
|
288 } |
|
289 |
|
290 if( markPos > 0 ) // mark icon will go somewhere after item string... |
|
291 { |
|
292 startPos = temp.Length(); |
|
293 endPos = temp.Length(); |
|
294 des.Append( temp.Left( startPos ) ); // first part of string |
|
295 des.Append( '\t' ); // column separator before mark icon was missing |
|
296 } |
|
297 else |
|
298 { |
|
299 des.Append( temp.Left( startPos ) ); // first part of string |
|
300 } |
|
301 |
|
302 TInt replace = repl.FindF(KMarkReplacementString); |
|
303 if (replace != KErrNotFound) // moving subcell |
|
304 { |
|
305 des.Append( repl.Left( replace ) ); |
|
306 // now we have first part of string + mark subcell |
|
307 // then add 1 moved subcell |
|
308 des.Append( temp.Mid( startPos, endPos-startPos ) ); |
|
309 |
|
310 // skip second moved subcell and add rest of the string |
|
311 while( endPos < temp.Length() ) |
|
312 { |
|
313 if( temp[endPos] == '\t' ) |
|
314 { |
|
315 break; |
|
316 } |
|
317 endPos++; |
|
318 } |
|
319 if( endPos < temp.Length() ) // this cuts off '\t' |
|
320 { |
|
321 endPos++; |
|
322 } |
|
323 des.Append( temp.Mid( endPos ) ); |
|
324 |
|
325 //is this needed - currently not used in S60? |
|
326 //buffer.Append(aReplacement->Mid(replace+2)); // 2 == length of %s |
|
327 } |
|
328 else // just replacement |
|
329 { |
|
330 des.Append( repl ); // no '%s' in replacement string |
|
331 des.Append( '\t' ); |
|
332 des.Append( temp.Mid( endPos ) ); |
|
333 } |
|
334 |
|
335 des.Set( buffer->Des() ); |
|
336 FormattedCellData()->Draw( Properties(aItemIndex), |
|
337 *iGc, |
|
338 &des, |
|
339 aItemTextRect, |
|
340 aItemIsCurrent && highlightShown, |
|
341 colors ); |
|
342 delete buffer; |
|
343 return; |
|
344 } |
|
345 } |
|
346 |
|
347 // normal drawing without mark icon |
|
348 FormattedCellData()->Draw( Properties(aItemIndex), |
|
349 *iGc, |
|
350 &temp, |
|
351 aItemTextRect, |
|
352 aItemIsCurrent && highlightShown, |
|
353 colors ); |
|
354 _AKNTRACE_FUNC_EXIT; |
|
355 } |
|
356 |
|
357 EXPORT_C TSize |
|
358 CFormattedCellListBoxItemDrawer::MinimumCellSize() const |
|
359 { |
|
360 CFormattedCellListBoxData* data=FormattedCellData(); |
|
361 const TInt cells=data->LastSubCell(); |
|
362 if (cells==-1) |
|
363 return CTextListItemDrawer::MinimumCellSize(); |
|
364 TInt width=0; |
|
365 TInt height=0; |
|
366 for(TInt ii=0;ii<cells;ii++) |
|
367 { |
|
368 TPoint endpos( data->SubCellPosition(ii) + data->SubCellSize(ii) ); |
|
369 if (endpos.iX > width) width = endpos.iX; |
|
370 if (endpos.iY > height) height = endpos.iY; |
|
371 } |
|
372 height+=VerticalInterItemGap(); |
|
373 return TSize(width,height); |
|
374 } |
|
375 |
|
376 |
|
377 EXPORT_C void CFormattedCellListBoxItemDrawer::DrawItemMark(TBool /*aItemIsSelected*/, TBool /*aViewIsDimmed*/, const TPoint& /*aMarkPos*/) const |
|
378 { |
|
379 } |
|
380 |
|
381 |
|
382 EXPORT_C TInt |
|
383 CFormattedCellListBoxItemDrawer::ItemWidthInPixels(TInt) const |
|
384 { |
|
385 TInt itemWidth = MinimumCellSize().iWidth; |
|
386 |
|
387 if (iDrawMark) |
|
388 itemWidth += (iMarkColumnWidth + iMarkGutter); |
|
389 return itemWidth; |
|
390 } |
|
391 |
|
392 EXPORT_C void CFormattedCellListBoxItemDrawer::SetItemCellSize( |
|
393 const TSize& aSizeInPixels ) |
|
394 { |
|
395 CTextListItemDrawer::SetItemCellSize( aSizeInPixels ); |
|
396 |
|
397 // Data needs the cell size to create/reconfigure highlight animations |
|
398 FormattedCellData()->SetItemCellSize( iItemCellSize ); |
|
399 } |
|
400 |
|
401 EXPORT_C void CFormattedCellListBoxItemDrawer::SetTopItemIndex(TInt aTop) |
|
402 { |
|
403 iTopItemIndex = aTop; |
|
404 } |
|
405 |
|
406 void |
|
407 CFormattedCellListBoxItemDrawer::DrawCurrentItemRect(const TRect& aRect) const |
|
408 { |
|
409 _AKNTRACE_FUNC_ENTER; |
|
410 iGc->SetClippingRect(iViewRect); |
|
411 iGc->SetBrushStyle(CGraphicsContext::ENullBrush); |
|
412 iGc->SetPenColor(iHighlightedBackColor); |
|
413 iGc->DrawRect(aRect); |
|
414 iGc->CancelClippingRect(); |
|
415 _AKNTRACE_FUNC_EXIT; |
|
416 } |
|
417 |
|
418 |
|
419 // |
|
420 // CEikFormattedCellListBox |
|
421 // |
|
422 |
|
423 EXPORT_C |
|
424 CEikFormattedCellListBox::CEikFormattedCellListBox() |
|
425 { |
|
426 AKNTASHOOK_ADD( this, "CEikFormattedCellListBox" ); |
|
427 } |
|
428 |
|
429 EXPORT_C void |
|
430 CEikFormattedCellListBox::ConstructFromResourceL(TResourceReader& aReader) |
|
431 { |
|
432 RestoreCommonListBoxPropertiesL(aReader); |
|
433 iRequiredCellCharWidth=aReader.ReadInt16(); |
|
434 |
|
435 iModel=new(ELeave) CAknFilteredTextListBoxModel; |
|
436 TInt array_id=aReader.ReadInt32(); |
|
437 if (!array_id) |
|
438 { |
|
439 ((CTextListBoxModel*)iModel)->ConstructL(); |
|
440 } |
|
441 else |
|
442 { |
|
443 CDesCArray* desArray=iCoeEnv->ReadDesCArrayResourceL(array_id); |
|
444 CleanupStack::PushL(desArray); |
|
445 |
|
446 ((CTextListBoxModel*)iModel)->ConstructL(desArray); |
|
447 CleanupStack::Pop(); |
|
448 } |
|
449 CreateItemDrawerL(); |
|
450 iItemDrawer->SetDrawMark(EFalse); |
|
451 |
|
452 EnableExtendedDrawingL(); |
|
453 |
|
454 ((CFormattedCellListBoxItemDrawer*)iItemDrawer)->SetCellWidthInChars(iRequiredCellCharWidth); |
|
455 CreateViewL(); |
|
456 } |
|
457 |
|
458 EXPORT_C void |
|
459 CEikFormattedCellListBox::ConstructL(const CCoeControl* aParent, |
|
460 TInt aFlags) |
|
461 { |
|
462 CAknFilteredTextListBoxModel* model=new(ELeave) CAknFilteredTextListBoxModel; |
|
463 iModel=model; |
|
464 model->ConstructL(); |
|
465 CreateItemDrawerL(); |
|
466 |
|
467 EnableExtendedDrawingL(); |
|
468 |
|
469 iItemDrawer->SetDrawMark(EFalse); |
|
470 CEikListBox::ConstructL(aParent,aFlags); |
|
471 } |
|
472 |
|
473 EXPORT_C CTextListBoxModel* |
|
474 CEikFormattedCellListBox::Model() const |
|
475 { |
|
476 return(CTextListBoxModel*)iModel; |
|
477 } |
|
478 |
|
479 EXPORT_C CFormattedCellListBoxItemDrawer* |
|
480 CEikFormattedCellListBox::ItemDrawer() const |
|
481 { |
|
482 return(CFormattedCellListBoxItemDrawer*)iItemDrawer; |
|
483 } |
|
484 |
|
485 EXPORT_C void CEikFormattedCellListBox::UseLogicalToVisualConversion( |
|
486 TBool aUseConversion ) |
|
487 { |
|
488 static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer )-> |
|
489 FormattedCellData()->UseLogicalToVisualConversion( |
|
490 aUseConversion ); |
|
491 } |
|
492 |
|
493 /** |
|
494 * Note that it must be possible to call this method multiple times. |
|
495 */ |
|
496 EXPORT_C void CEikFormattedCellListBox::EnableExtendedDrawingL() |
|
497 { |
|
498 // Assert that the item drawer has been created before calling this method. |
|
499 __ASSERT_DEBUG( ItemDrawer() && ItemDrawer()->FormattedCellData(), |
|
500 Panic( EAknPanicListBoxItemDrawerNotCreated ) ); |
|
501 |
|
502 CFormattedCellListBoxData* data = ItemDrawer()->FormattedCellData(); |
|
503 |
|
504 data->SetControl( this ); |
|
505 // Can be created only after the control has been set. |
|
506 data->CreatePictographInterfaceL(); |
|
507 // Can be created only after the control has been set. |
|
508 data->CreateMarqueeControlL(); |
|
509 } |
|
510 |
|
511 #ifdef RD_LIST_STRETCH |
|
512 EXPORT_C void CEikFormattedCellListBox::EnableStretching( const TBool aEnabled ) |
|
513 { |
|
514 if ( ItemDrawer()->FormattedCellData()->StretchingEnabled() != aEnabled ) |
|
515 { |
|
516 ItemDrawer()->FormattedCellData()->EnableStretching( aEnabled ); |
|
517 SizeChanged(); |
|
518 } |
|
519 } |
|
520 #else |
|
521 EXPORT_C void CEikFormattedCellListBox::EnableStretching( const TBool /*aEnabled*/ ) |
|
522 { |
|
523 } |
|
524 #endif // RD_LIST_STRETCH |
|
525 |
|
526 #ifdef RD_LIST_STRETCH |
|
527 EXPORT_C void CEikFormattedCellListBox::HideSecondRow( const TBool aHide ) |
|
528 { |
|
529 if ( ItemDrawer()->FormattedCellData()->SecondRowHidden() != aHide ) |
|
530 { |
|
531 ItemDrawer()->FormattedCellData()->HideSecondRow( aHide ); |
|
532 SizeChanged(); |
|
533 } |
|
534 } |
|
535 #else |
|
536 EXPORT_C void CEikFormattedCellListBox::HideSecondRow( const TBool /*aHide*/ ) |
|
537 { |
|
538 } |
|
539 #endif // RD_LIST_STRETCH |
|
540 |
|
541 EXPORT_C void |
|
542 CEikFormattedCellListBox::CreateItemDrawerL() |
|
543 { |
|
544 CFormattedCellListBoxData* cellData=CFormattedCellListBoxData::NewL(); |
|
545 CleanupStack::PushL( cellData ); |
|
546 iItemDrawer=new(ELeave) CFormattedCellListBoxItemDrawer(Model(), iEikonEnv->NormalFont(), cellData); |
|
547 CleanupStack::Pop(); |
|
548 } |
|
549 |
|
550 EXPORT_C TInt CEikFormattedCellListBox::AdjustRectHeightToWholeNumberOfItems(TRect &aRect) const |
|
551 { |
|
552 TInt remainder = aRect.Height() % iItemHeight; |
|
553 aRect.iBr.iY -= remainder; |
|
554 |
|
555 return remainder; |
|
556 } |
|
557 |
|
558 EXPORT_C CListBoxView* |
|
559 CEikFormattedCellListBox::MakeViewClassInstanceL() |
|
560 { |
|
561 return (new(ELeave) CFormattedCellListBoxView); |
|
562 } |
|
563 |
|
564 EXPORT_C void CEikFormattedCellListBox::FocusChanged( TDrawNow aDrawNow ) |
|
565 { |
|
566 CEikTextListBox::FocusChanged( aDrawNow ); |
|
567 |
|
568 // Data needs focus change information to control animations. |
|
569 if( IsFocused() ) |
|
570 { |
|
571 ItemDrawer()->FormattedCellData()->FocusGained(); |
|
572 } |
|
573 else |
|
574 { |
|
575 ItemDrawer()->FormattedCellData()->FocusLost(); |
|
576 } |
|
577 } |
|
578 |
|
579 EXPORT_C void |
|
580 CEikFormattedCellListBox::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const |
|
581 { |
|
582 CEikTextListBox::GetColorUseListL(aColorUseList); |
|
583 } |
|
584 |
|
585 EXPORT_C void |
|
586 CEikFormattedCellListBox::HandleResourceChange(TInt aType) |
|
587 { |
|
588 _AKNTRACE_FUNC_ENTER; |
|
589 if ( aType == KEikDynamicLayoutVariantSwitch ) |
|
590 { |
|
591 _AKNTRACE("CEikFormattedCellListBox::HandleResourceChange type=KEikDynamicLayoutVariantSwitch"); |
|
592 TRAP_IGNORE( |
|
593 ItemDrawer()->FormattedCellData()->SetupSkinContextL() ); |
|
594 } |
|
595 |
|
596 CEikTextListBox::HandleResourceChange(aType); |
|
597 ItemDrawer()->FormattedCellData()->HandleResourceChange( aType ); |
|
598 _AKNTRACE_FUNC_EXIT; |
|
599 } |
|
600 |
|
601 EXPORT_C TTypeUid::Ptr CEikFormattedCellListBox::MopSupplyObject(TTypeUid aId) |
|
602 { |
|
603 if ( aId.iUid == MAknsControlContext::ETypeId ) |
|
604 { |
|
605 return MAknsControlContext::SupplyMopObject( |
|
606 aId, ItemDrawer()->ColumnData()->SkinBackgroundContext() ); |
|
607 } |
|
608 return CEikTextListBox::MopSupplyObject( aId ); |
|
609 } |
|
610 |
|
611 // This helper function sets icon sizes for visible list items. |
|
612 void CEikFormattedCellListBox::SetIconSizes() |
|
613 { |
|
614 // No icon size setting when kinetic scrolling enabled |
|
615 if ( ItemDrawer()->ColumnData()->KineticScrollingEnabled() ) |
|
616 { |
|
617 return; |
|
618 } |
|
619 // if you modify this method, check also eikclb.cpp |
|
620 if (!IsReadyToDraw()) |
|
621 { |
|
622 return; // can't access listdata yet |
|
623 } |
|
624 |
|
625 TInt numOfItems = Model()->NumberOfItems(); |
|
626 // we have a filtered list, and it's item count might not be correct |
|
627 // since this is called when filtered model and text list box model |
|
628 // have yet not synced their item count |
|
629 CAknListBoxFilterItems *filter = STATIC_CAST(CAknFilteredTextListBoxModel*,Model())->Filter(); |
|
630 if (filter) |
|
631 //if ( Model()->MatchableTextArray() ) // read as: if ( HaveFilter() ) |
|
632 { |
|
633 // so we need to use this ugly hack |
|
634 TInt n = Model()->MatchableTextArray()->MdcaCount(); |
|
635 numOfItems = n > numOfItems ? numOfItems : n; |
|
636 } |
|
637 |
|
638 |
|
639 if (numOfItems == 0) // no need to parse anything |
|
640 return; |
|
641 |
|
642 CArrayPtr<CGulIcon>* icons = ItemDrawer()->FormattedCellData()->IconArray(); |
|
643 |
|
644 if (!icons || icons->Count() == 0) // no icons set yet |
|
645 return; |
|
646 |
|
647 TPtrC iconText; |
|
648 TInt iconIndex; |
|
649 TSize iconSize(0,0); |
|
650 |
|
651 for (TInt row=View()->TopItemIndex(); row <= View()->BottomItemIndex(); row++) |
|
652 { |
|
653 if (row >= numOfItems) |
|
654 { |
|
655 continue; // grid may have bottomitemindex bigger than item count |
|
656 } |
|
657 const TDesC &txt = Model()->ItemText(row); |
|
658 |
|
659 for (TInt subCell=0; subCell<6; subCell++) |
|
660 { |
|
661 iconSize = ItemDrawer()->FormattedCellData()->GetSubCellIconSize(subCell); |
|
662 // only those subcells that have icons, have also icon size set |
|
663 if (iconSize.iWidth == 0 || iconSize.iHeight == 0) |
|
664 { |
|
665 continue; // no need to set icon size |
|
666 } |
|
667 TextUtils::ColumnText(iconText, subCell, &txt); // get icon index(text) |
|
668 |
|
669 TLex iconLex(iconText); |
|
670 |
|
671 if (iconLex.Val(iconIndex) != KErrNone) |
|
672 { |
|
673 iconIndex = -1; |
|
674 } |
|
675 |
|
676 CGulIcon *icon; |
|
677 CFbsBitmap *bitmap; |
|
678 TInt realIndex; |
|
679 |
|
680 while(iconIndex >= 0) |
|
681 { |
|
682 if (iconIndex > 0xffff) |
|
683 { |
|
684 realIndex = iconIndex >> 16; // first set highlight icon |
|
685 iconIndex = iconIndex & 0xffff; |
|
686 } |
|
687 else |
|
688 { |
|
689 realIndex = iconIndex; |
|
690 iconIndex = -1; |
|
691 } |
|
692 |
|
693 if ( realIndex > icons->Count() -1 ) |
|
694 { |
|
695 break; |
|
696 } |
|
697 icon = (*icons)[realIndex]; |
|
698 if (!icon) |
|
699 { |
|
700 break; |
|
701 } |
|
702 bitmap = icon->Bitmap(); |
|
703 if (!bitmap) |
|
704 { |
|
705 break; |
|
706 } |
|
707 /* note, that SetSize() must be called with |
|
708 * EAspectRatioPreservedAndUnusedSpaceRemoved, |
|
709 * otherwise centering/aligning code in CColumnListBoxData::Draw() |
|
710 * will not work. Default EAspectRatioPreserved parameter |
|
711 * will fill icon with blank extra space, and icon will then |
|
712 * be exactly same size as space reserved for it. Extra blank |
|
713 * space would be added to right side of the icon. |
|
714 */ |
|
715 AknIconUtils::SetSize( bitmap, |
|
716 iconSize, |
|
717 EAspectRatioPreservedAndUnusedSpaceRemoved ); |
|
718 } |
|
719 |
|
720 |
|
721 |
|
722 /*switch(1) |
|
723 { |
|
724 case 1: |
|
725 default: |
|
726 if ( iconIndex < 0 || iconIndex > icons->Count() -1 ) |
|
727 { |
|
728 break; |
|
729 } |
|
730 |
|
731 icon = (*icons)[iconIndex]; |
|
732 if (!icon) |
|
733 { |
|
734 break; |
|
735 } |
|
736 |
|
737 bitmap = icon->Bitmap(); |
|
738 |
|
739 if (!bitmap) |
|
740 { |
|
741 break; |
|
742 }*/ |
|
743 /* note, that SetSize() must be called with |
|
744 * EAspectRatioPreservedAndUnusedSpaceRemoved, |
|
745 * otherwise centering/aligning code in CColumnListBoxData::Draw() |
|
746 * will not work. Default EAspectRatioPreserved parameter |
|
747 * will fill icon with blank extra space, and icon will then |
|
748 * be exactly same size as space reserved for it. Extra blank |
|
749 * space would be added to right side of the icon. |
|
750 */ |
|
751 // AknIconUtils::SetSize( bitmap, |
|
752 // iconSize, |
|
753 // EAspectRatioPreservedAndUnusedSpaceRemoved ); |
|
754 // } |
|
755 } // end subCell for |
|
756 } // end row for |
|
757 } |
|
758 |
|
759 EXPORT_C void CEikFormattedCellListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
760 { |
|
761 _AKNTRACE_FUNC_ENTER; |
|
762 CEikTextListBox::HandlePointerEventL(aPointerEvent); |
|
763 _AKNTRACE_FUNC_EXIT; |
|
764 } |
|
765 |
|
766 EXPORT_C void* CEikFormattedCellListBox::ExtensionInterface( TUid /*aInterface*/ ) |
|
767 { |
|
768 return NULL; |
|
769 } |
|
770 |
|
771 EXPORT_C void CEikFormattedCellListBox::CEikListBox_Reserved() |
|
772 { |
|
773 } |
|
774 |
|
775 #define ITEM_EXISTS_BEGIN TInt no_of_items__ = iModel->NumberOfItems() |
|
776 #define ITEM_EXISTS(x) (((x) > -1) && ((x) < no_of_items__)) |
|
777 |
|
778 #define ITEM_EXISTS_ONCE(x) (((x) > -1) && ((x) < iModel->NumberOfItems())) |
|
779 |
|
780 EXPORT_C void |
|
781 CFormattedCellListBoxView::Draw(const TRect* clipRect) const |
|
782 { |
|
783 _AKNTRACE_FUNC_ENTER; |
|
784 if ( RedrawDisabled() || !IsVisible() ) |
|
785 { |
|
786 _AKNTRACE("CFormattedCellListBoxView::Draw return because redraw disabled or invisible"); |
|
787 _AKNTRACE_FUNC_EXIT; |
|
788 return; |
|
789 } |
|
790 |
|
791 if(clipRect && clipRect->IsEmpty()) |
|
792 { |
|
793 _AKNTRACE("CFormattedCellListBoxView::Draw return because clip rect is empty"); |
|
794 _AKNTRACE_FUNC_EXIT; |
|
795 return; |
|
796 } |
|
797 |
|
798 TInt i = iTopItemIndex; |
|
799 CFormattedCellListBoxItemDrawer *itemDrawer = static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer ); |
|
800 MAknsSkinInstance *skin = AknsUtils::SkinInstance(); |
|
801 CCoeControl* control = itemDrawer->FormattedCellData()->Control(); |
|
802 MAknsControlContext *cc = AknsDrawUtils::ControlContext( control ); |
|
803 |
|
804 if ( !cc ) |
|
805 { |
|
806 cc = itemDrawer->FormattedCellData()->SkinBackgroundContext(); |
|
807 } |
|
808 |
|
809 itemDrawer->SetTopItemIndex( iTopItemIndex ); |
|
810 |
|
811 if ( iModel->NumberOfItems() > 0 ) |
|
812 { |
|
813 TBool drawingInitiated = ETrue; |
|
814 |
|
815 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
816 MAknListBoxTfxInternal* transApi = |
|
817 CAknListLoader::TfxApiInternal( iGc ); |
|
818 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
819 |
|
820 if ( CAknEnv::Static()->TransparencyEnabled() ) |
|
821 { |
|
822 if ( iWin && iWin->GetDrawRect() == TRect::EUninitialized ) |
|
823 { |
|
824 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
825 drawingInitiated = transApi && !transApi->EffectsDisabled(); |
|
826 #else |
|
827 drawingInitiated = EFalse; |
|
828 #endif |
|
829 } |
|
830 |
|
831 if ( !drawingInitiated ) |
|
832 { |
|
833 iWin->Invalidate( *clipRect ); |
|
834 iWin->BeginRedraw( *clipRect ); |
|
835 } |
|
836 } |
|
837 |
|
838 TInt lastPotentialItemIndex = Min( iModel->NumberOfItems(), iTopItemIndex + NumberOfItemsThatFitInRect( iViewRect ) ); |
|
839 |
|
840 while ( i < lastPotentialItemIndex ) |
|
841 { |
|
842 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
843 if ( transApi ) |
|
844 { |
|
845 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); |
|
846 } |
|
847 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
848 |
|
849 iGc->SetClippingRect( iViewRect ); |
|
850 |
|
851 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
852 if ( transApi ) |
|
853 { |
|
854 transApi->StopDrawing(); |
|
855 } |
|
856 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
857 |
|
858 DrawItem( i++ ); |
|
859 |
|
860 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
861 if ( transApi ) |
|
862 { |
|
863 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); |
|
864 } |
|
865 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
866 |
|
867 iGc->CancelClippingRect(); |
|
868 |
|
869 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
870 if ( transApi ) |
|
871 { |
|
872 transApi->StopDrawing(); |
|
873 } |
|
874 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
875 } |
|
876 |
|
877 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
878 if ( transApi ) |
|
879 { |
|
880 transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); |
|
881 } |
|
882 if ( i > iBottomItemIndex + 1 ) |
|
883 { |
|
884 i = iBottomItemIndex + 1; |
|
885 } |
|
886 TRect usedPortionOfViewRect( iViewRect.iTl+TSize(0,iVerticalOffset), TSize( iViewRect.Width(), ( i - iTopItemIndex ) * iItemHeight ) ); |
|
887 #else |
|
888 // clear the unused portion of the viewing area |
|
889 TRect usedPortionOfViewRect( iViewRect.iTl.iX, iViewRect.iTl.iY + iVerticalOffset, iViewRect.Width(), ItemPos( lastPotentialItemIndex ).iY ); |
|
890 |
|
891 if ( clipRect ) |
|
892 { |
|
893 usedPortionOfViewRect.iBr.iX = clipRect->iBr.iX; |
|
894 } |
|
895 |
|
896 #endif |
|
897 |
|
898 // also clear area behind scroll bar. |
|
899 // this is a terrible hack, which is unfortunately needed since layouts |
|
900 // leave 2 pixel (in double res) wide margins to both sides of the |
|
901 // scroll bar, and there is no other way to do this. This hack is |
|
902 // only really valid for main pane lists, but it does not seem to |
|
903 // break popup lists, popup field lists or setting page radiobutton |
|
904 // lists. |
|
905 // See also: eikslb.cpp, eikclb.cpp |
|
906 TRect sbbg( iViewRect ); // whole area behind scroll bar |
|
907 TRect margin( iViewRect ); // it gets even worse in mirrored layouts |
|
908 |
|
909 if ( AknLayoutUtils::LayoutMirrored() ) |
|
910 { |
|
911 _AKNTRACE("CFormattedCellListBoxView::Draw Layout mirrored"); |
|
912 sbbg.iBr.iX = iViewRect.iBr.iX - itemDrawer->LafItemSize().iWidth; |
|
913 |
|
914 // in mirrored layouts we also need to draw a margin slice in right |
|
915 TRect mainPane; |
|
916 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, |
|
917 mainPane ); |
|
918 TAknLayoutRect listscrollAppPane; |
|
919 listscrollAppPane.LayoutRect( mainPane, |
|
920 AknLayoutScalable_Avkon::listscroll_app_pane( 0 ) ); |
|
921 |
|
922 TInt rMargin = mainPane.iBr.iX - listscrollAppPane.Rect().iBr.iX; |
|
923 margin.iTl.iX = margin.iBr.iX - rMargin; |
|
924 } |
|
925 else |
|
926 { |
|
927 sbbg.iTl.iX = iViewRect.iTl.iX + itemDrawer->LafItemSize().iWidth; |
|
928 } |
|
929 |
|
930 // Unused portion will be cleared only if listbox background is drawn. |
|
931 if ( itemDrawer->ColumnData()->IsBackgroundDrawingEnabled() ) |
|
932 { |
|
933 if ( control ) |
|
934 { |
|
935 if ( !control->FindBackground() ) |
|
936 { |
|
937 AknsDrawUtils::BackgroundBetweenRects( skin, |
|
938 cc, |
|
939 control, |
|
940 *iGc, |
|
941 iViewRect, |
|
942 usedPortionOfViewRect ); |
|
943 |
|
944 AknsDrawUtils::Background( skin, cc, control, *iGc, sbbg ); |
|
945 |
|
946 if ( AknLayoutUtils::LayoutMirrored() ) |
|
947 { |
|
948 AknsDrawUtils::Background( skin, cc, control, *iGc, margin ); |
|
949 } |
|
950 } |
|
951 } |
|
952 else |
|
953 { |
|
954 iGc->SetBrushColor( BackColor() ); |
|
955 DrawUtils::ClearBetweenRects( *iGc, iViewRect, usedPortionOfViewRect ); |
|
956 iGc->Clear( sbbg ); |
|
957 |
|
958 if ( AknLayoutUtils::LayoutMirrored() ) |
|
959 { |
|
960 iGc->Clear( margin ); |
|
961 } |
|
962 } |
|
963 } |
|
964 |
|
965 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
966 if ( transApi ) |
|
967 { |
|
968 transApi->StopDrawing(); |
|
969 } |
|
970 #endif //RD_UI_TRANSITION_EFFECTS_LIST |
|
971 |
|
972 |
|
973 if ( CAknEnv::Static()->TransparencyEnabled() && !drawingInitiated ) |
|
974 { |
|
975 iWin->EndRedraw(); |
|
976 } |
|
977 } |
|
978 _AKNTRACE_FUNC_EXIT; |
|
979 } |
|
980 |
|
981 EXPORT_C void CFormattedCellListBoxItemDrawer::ClearAllPropertiesL() |
|
982 { |
|
983 delete iPropertyArray; |
|
984 iPropertyArray = NULL; |
|
985 iPropertyArray = new (ELeave) CArrayFixFlat<SListProperties>(2); |
|
986 } |
|
987 |
|
988 EXPORT_C void CFormattedCellListBoxItemDrawer::SetPropertiesL(TInt aItemIndex, TListItemProperties aProperty) |
|
989 { |
|
990 if (!iPropertyArray) ClearAllPropertiesL(); |
|
991 TInt index; |
|
992 TKeyArrayFix key(0,ECmpTInt); |
|
993 SListProperties prop; |
|
994 prop.iItem = aItemIndex; |
|
995 TInt error = iPropertyArray->FindIsq(prop, key, index); |
|
996 if (error) |
|
997 { // not found, error is nonzero. |
|
998 iPropertyArray->InsertIsqL(prop, key); |
|
999 iPropertyArray->FindIsq(prop, key, index); |
|
1000 } |
|
1001 iPropertyArray->At(index).iProperties = aProperty; |
|
1002 } |
|
1003 |
|
1004 EXPORT_C |
|
1005 TListItemProperties CFormattedCellListBoxItemDrawer::Properties(TInt aItemIndex) const |
|
1006 { |
|
1007 |
|
1008 if (!iPropertyArray) return CTextListItemDrawer::Properties(aItemIndex); |
|
1009 CAknListBoxFilterItems *filter = STATIC_CAST(CAknFilteredTextListBoxModel*,iModel)->Filter(); |
|
1010 if (filter) |
|
1011 { |
|
1012 aItemIndex = filter->FilteredItemIndex(aItemIndex); |
|
1013 } |
|
1014 TKeyArrayFix key(0,ECmpTInt); |
|
1015 SListProperties prop; |
|
1016 prop.iItem = aItemIndex; |
|
1017 TInt index; |
|
1018 TInt error = iPropertyArray->FindIsq(prop, key, index); |
|
1019 if (error) return CTextListItemDrawer::Properties(aItemIndex); |
|
1020 return iPropertyArray->At(index).iProperties; |
|
1021 } |
|
1022 |
|
1023 |
|
1024 static TBool WasClippedHack( const TDesC& aColumntowrap, |
|
1025 const TDesC& aWrappedText, |
|
1026 const TDesC& aSecondLine ) |
|
1027 |
|
1028 { |
|
1029 // this seems to be only way of chekcing if WrapToArrayL() clipped |
|
1030 // text or not. Unless you rewrite half of AknBidiTextUtils && |
|
1031 // AknTextWrapper. sigh. |
|
1032 TBool clipped2( EFalse ); |
|
1033 TInt len ( aColumntowrap.Length() ); // length of given text |
|
1034 TInt wl( aWrappedText.Length() ); // length of 1st + 2nd line |
|
1035 |
|
1036 // text will be wrapped at \n or ' ' and that whitespace will be |
|
1037 // discarded. a BIG assumption is made here, that there are no |
|
1038 // double spaces in item string at wrapping point. If there are, |
|
1039 // this does not work as intended. |
|
1040 len--; |
|
1041 |
|
1042 if ( len > wl ) |
|
1043 { |
|
1044 clipped2 = ETrue; |
|
1045 } |
|
1046 else if ( len == wl ) |
|
1047 { |
|
1048 // border case. Only way to check the wrapping is really to |
|
1049 // check for ellipsis... too bad that WrapToArrayL() does not |
|
1050 // return any info about clipping. Ellipsis will be either at |
|
1051 // end of the 2nd string or at start of 2nd string, if |
|
1052 // mirrored layout is used. Of course, this fails, if length |
|
1053 // is suitable and there is a ellipsis in the item string. Or |
|
1054 // if someone manages to create a item string with say arabic |
|
1055 // & latin characters in such way, that WrapToArrayL() inserts |
|
1056 // ellipsis in the middle of the string. |
|
1057 if ( aSecondLine[0] == KEllipsis || aSecondLine[aSecondLine.Length() - 1] == KEllipsis ) |
|
1058 { |
|
1059 clipped2 = ETrue; |
|
1060 } |
|
1061 } |
|
1062 return clipped2; |
|
1063 } |
|
1064 |
|
1065 void |
|
1066 CFormattedCellListBoxItemDrawer::WordWrapListItem( TPtr& aTarget, |
|
1067 const TDesC &aItemString, |
|
1068 TInt aFirstIndex, |
|
1069 TInt aSecondIndex, |
|
1070 TInt aItemIndex ) const |
|
1071 { |
|
1072 TPtrC columntowrap; |
|
1073 TextUtils::ColumnText(columntowrap, aFirstIndex, &aItemString); |
|
1074 |
|
1075 if ( !columntowrap.Length() ) |
|
1076 { |
|
1077 // if nothing to wrap, return string unmodified. Wrapping |
|
1078 // empty string results in chaos. |
|
1079 aTarget.Append( aItemString ); |
|
1080 return; |
|
1081 } |
|
1082 |
|
1083 // Set to real values after wrapping successfully done |
|
1084 TInt firstWordWrappedSubcellIndex = -1; |
|
1085 TInt secondWordWrappedSubcellIndex = -1; |
|
1086 |
|
1087 // for informing CurrentItemTextWasClipped() about clipping performed here |
|
1088 TBool clipped1( EFalse ); |
|
1089 TBool clipped2( EFalse ); |
|
1090 // must be cleared, otherwize this will leave bits on |
|
1091 FormattedCellData()->SetClippedByWrap( 0, EFalse ); |
|
1092 |
|
1093 // we have to adjust column widths here if there are any optional icons shown |
|
1094 TRect firstRect( FormattedCellData()->SubCellPosition(aFirstIndex), |
|
1095 FormattedCellData()->SubCellSize(aFirstIndex) ); |
|
1096 TRect secondRect( FormattedCellData()->SubCellPosition(aSecondIndex), |
|
1097 FormattedCellData()->SubCellSize(aSecondIndex) ); |
|
1098 TRect overlapRect; |
|
1099 TInt lastSC = FormattedCellData()->LastSubCell(); |
|
1100 |
|
1101 TPtrC scString; |
|
1102 TBool firstClippedLeft = EFalse; |
|
1103 TBool firstClippedRight = EFalse; |
|
1104 TBool secondClippedLeft = EFalse; |
|
1105 TBool secondClippedRight = EFalse; |
|
1106 |
|
1107 // this should be rewritten for drawformatted_simple - no need to |
|
1108 // compare rects when layoutdata provides info directly. |
|
1109 // it might be possible to get rid of compabitility code in |
|
1110 // SetGraphic|Text|ConditionalSubcell then, altough |
|
1111 // some exported methods in Eikfrlbd.cpp might benefit from them |
|
1112 |
|
1113 for (TInt subCell=0; subCell <= lastSC; subCell++ ) |
|
1114 { |
|
1115 TextUtils::ColumnText(scString, subCell, &aItemString); |
|
1116 if ( scString.Length() |
|
1117 && FormattedCellData()->SubCellIsNotAlwaysDrawn(subCell) ) |
|
1118 { |
|
1119 // we have possible overlapping subcell, adjust both firstWidth and |
|
1120 // secondWidth accordingly |
|
1121 overlapRect.SetRect( FormattedCellData()->SubCellPosition(subCell), |
|
1122 FormattedCellData()->SubCellSize(subCell) ); |
|
1123 if (firstRect.Intersects(overlapRect)) |
|
1124 { |
|
1125 if ((overlapRect.iTl.iX-firstRect.iTl.iX) > (firstRect.iBr.iX-overlapRect.iBr.iX)) |
|
1126 { |
|
1127 // overlapping rect is on the right side of first rect |
|
1128 firstRect.iBr.iX = overlapRect.iTl.iX; |
|
1129 firstClippedRight = ETrue; |
|
1130 } |
|
1131 else |
|
1132 { |
|
1133 // overlapping rect is on the left side of first rect |
|
1134 firstRect.iTl.iX = overlapRect.iBr.iX; |
|
1135 firstClippedLeft = ETrue; |
|
1136 } |
|
1137 } |
|
1138 if (secondRect.Intersects(overlapRect)) |
|
1139 { |
|
1140 if ((overlapRect.iTl.iX-firstRect.iTl.iX) > (firstRect.iBr.iX-overlapRect.iBr.iX)) |
|
1141 { |
|
1142 // overlapping rect is on the right side of second rect |
|
1143 secondRect.iBr.iX = overlapRect.iTl.iX; |
|
1144 secondClippedRight = ETrue; |
|
1145 } |
|
1146 else |
|
1147 { |
|
1148 // overlapping rect is on the left side of second rect |
|
1149 secondRect.iTl.iX = overlapRect.iBr.iX; |
|
1150 secondClippedLeft = ETrue; |
|
1151 } |
|
1152 } |
|
1153 } |
|
1154 else |
|
1155 { |
|
1156 continue; |
|
1157 } |
|
1158 } |
|
1159 |
|
1160 |
|
1161 TRAPD( error, |
|
1162 { |
|
1163 TPtrC firstString=columntowrap; |
|
1164 TPtrC secondString; |
|
1165 TextUtils::ColumnText(secondString, aSecondIndex, &aItemString); |
|
1166 |
|
1167 TInt firstWidth = firstRect.Width(); |
|
1168 if (!firstClippedLeft) |
|
1169 { |
|
1170 firstWidth -= FormattedCellData()->SubCellMargins(aFirstIndex).iLeft; |
|
1171 } |
|
1172 if (!firstClippedRight) |
|
1173 { |
|
1174 firstWidth -= FormattedCellData()->SubCellMargins(aFirstIndex).iRight; |
|
1175 } |
|
1176 |
|
1177 TInt secondWidth = secondRect.Width(); |
|
1178 if (!secondClippedLeft) |
|
1179 { |
|
1180 secondWidth -= FormattedCellData()->SubCellMargins(aSecondIndex).iLeft; |
|
1181 } |
|
1182 if (!secondClippedRight) |
|
1183 { |
|
1184 secondWidth -= FormattedCellData()->SubCellMargins(aSecondIndex).iRight; |
|
1185 } |
|
1186 |
|
1187 CArrayFixFlat<TPtrC>* resultArray = new( ELeave ) CArrayFixFlat<TPtrC>( 2 ); |
|
1188 CleanupStack::PushL( resultArray ); |
|
1189 |
|
1190 HBufC *wrapped = HBufC::NewLC( KMaxTotalDataLength + 2 * KAknBidiExtraSpacePerLine ); |
|
1191 HBufC *temptarget = HBufC::NewLC( KMaxTotalDataLength ); |
|
1192 |
|
1193 // java, among others, may use separate fonts for each row |
|
1194 const CFont* font1 = FormattedCellData()->RowAndSubCellFont( aItemIndex, aFirstIndex ) |
|
1195 ? FormattedCellData()->RowAndSubCellFont( aItemIndex, aFirstIndex ) |
|
1196 : FormattedCellData()->SubCellFont( aFirstIndex ); |
|
1197 |
|
1198 const CFont* font2 = FormattedCellData()->RowAndSubCellFont( aItemIndex, aSecondIndex ) |
|
1199 ? FormattedCellData()->RowAndSubCellFont( aItemIndex, aSecondIndex ) |
|
1200 : FormattedCellData()->SubCellFont( aSecondIndex ); |
|
1201 |
|
1202 // If second string is not empty, truncate both first and second |
|
1203 // line separately in their own lines. It is assumed here that these 2 lines |
|
1204 // are completely separate and do not share any context. |
|
1205 |
|
1206 if ( secondString.Length() ) |
|
1207 { |
|
1208 HBufC* convertedLine1 = HBufC::NewLC( firstString.Size() |
|
1209 + KAknBidiExtraSpacePerLine ); |
|
1210 |
|
1211 TPtr ptr1 = convertedLine1->Des(); |
|
1212 |
|
1213 HBufC* convertedLine2 = HBufC::NewLC( secondString.Size() |
|
1214 + KAknBidiExtraSpacePerLine ); |
|
1215 |
|
1216 TPtr ptr2 = convertedLine2->Des(); |
|
1217 |
|
1218 clipped1 = AknBidiTextUtils::ConvertToVisualAndClip( |
|
1219 firstString, |
|
1220 ptr1, |
|
1221 font1 ? *font1 : *LatinBold13(), |
|
1222 firstWidth, |
|
1223 firstWidth ); |
|
1224 |
|
1225 resultArray->AppendL( TPtrC( *convertedLine1 ) ); |
|
1226 |
|
1227 clipped2 = AknBidiTextUtils::ConvertToVisualAndClip( |
|
1228 secondString, |
|
1229 ptr2, |
|
1230 font2 ? *font2 : *LatinBold13(), |
|
1231 secondWidth, |
|
1232 secondWidth ); |
|
1233 |
|
1234 resultArray->AppendL( TPtrC( *convertedLine2 ) ); |
|
1235 } |
|
1236 else // Otherwise, wrap the first string in 2 lines |
|
1237 { |
|
1238 CArrayFixFlat<TInt>* lineWidthArray = |
|
1239 new( ELeave ) CArrayFixFlat<TInt>( 2 ); |
|
1240 CleanupStack::PushL( lineWidthArray ); |
|
1241 |
|
1242 lineWidthArray->AppendL(firstWidth); |
|
1243 lineWidthArray->AppendL(secondWidth); |
|
1244 |
|
1245 *wrapped = columntowrap.Left( KMaxTotalDataLength ); |
|
1246 TPtr ptr = wrapped->Des(); |
|
1247 |
|
1248 // this fails to truncate correctly, if lines use different fonts |
|
1249 AknBidiTextUtils::ConvertToVisualAndWrapToArrayL( |
|
1250 ptr, |
|
1251 *lineWidthArray, |
|
1252 font1 ? *font1 : *LatinBold13(), |
|
1253 *resultArray, |
|
1254 ETrue ); |
|
1255 |
|
1256 CleanupStack::PopAndDestroy(); // lineWidthArray |
|
1257 } |
|
1258 |
|
1259 TInt count = resultArray->Count(); |
|
1260 if (count > 0) |
|
1261 { |
|
1262 TPtr ttp = temptarget->Des(); |
|
1263 AknLAFUtils::ReplaceColumn( ttp, |
|
1264 CONST_CAST(TDesC*,&aItemString), |
|
1265 &resultArray->At(0), |
|
1266 '\t', |
|
1267 aFirstIndex ); |
|
1268 |
|
1269 firstWordWrappedSubcellIndex = aFirstIndex; |
|
1270 |
|
1271 if (count > 1) |
|
1272 { |
|
1273 AknLAFUtils::ReplaceColumn( aTarget, |
|
1274 temptarget, |
|
1275 &resultArray->At(1), |
|
1276 '\t', |
|
1277 aSecondIndex ); |
|
1278 secondWordWrappedSubcellIndex = aSecondIndex; |
|
1279 } |
|
1280 else |
|
1281 { |
|
1282 TPtrC empty = secondString; |
|
1283 AknLAFUtils::ReplaceColumn( aTarget, |
|
1284 temptarget, |
|
1285 &empty, |
|
1286 '\t', |
|
1287 aSecondIndex ); |
|
1288 } |
|
1289 |
|
1290 // unfortunately, ConvertToVisualAndWrapToArrayL() does |
|
1291 // not tell if last line was clipped. Hack around. |
|
1292 if ( count > 1 ) |
|
1293 { |
|
1294 clipped2 = WasClippedHack( columntowrap, wrapped->Des(), resultArray->At(1) ); |
|
1295 } |
|
1296 } |
|
1297 else |
|
1298 { |
|
1299 // Error, use default |
|
1300 TPtrC empty = firstString; |
|
1301 AknLAFUtils::ReplaceColumn( aTarget, &empty, &empty, |
|
1302 '\t', aFirstIndex ); |
|
1303 } |
|
1304 |
|
1305 CleanupStack::PopAndDestroy(); // temptarget |
|
1306 if (secondString.Length()) |
|
1307 { |
|
1308 CleanupStack::PopAndDestroy(2); // convertedLine1, convertedLine2 |
|
1309 } |
|
1310 |
|
1311 CleanupStack::PopAndDestroy(2); // wrapped, resultArray |
|
1312 } |
|
1313 |
|
1314 ); // end of TRAP |
|
1315 if ( error != KErrNone ) |
|
1316 { |
|
1317 aTarget.Append(aItemString); |
|
1318 } |
|
1319 |
|
1320 // Inform drawing routine of word wrapped subcells, which are already |
|
1321 // converted from logical to visual form. |
|
1322 // This method is called for each list item before drawing it. |
|
1323 FormattedCellData()->SetWordWrappedSubcellIndices( |
|
1324 firstWordWrappedSubcellIndex, |
|
1325 secondWordWrappedSubcellIndex ); |
|
1326 |
|
1327 // pass info for CurrentItemTextWasClipped() |
|
1328 TInt clippedCells( 0 ); |
|
1329 |
|
1330 if ( clipped1 ) |
|
1331 { |
|
1332 clippedCells |= ( 1 << firstWordWrappedSubcellIndex ); |
|
1333 } |
|
1334 |
|
1335 if ( clipped2 ) |
|
1336 { |
|
1337 clippedCells |= ( 1 << secondWordWrappedSubcellIndex ); |
|
1338 } |
|
1339 |
|
1340 FormattedCellData()->SetClippedByWrap( clippedCells, ETrue ); |
|
1341 } |
|
1342 |
|
1343 EXPORT_C void CFormattedCellListBoxItemDrawer::CFormattedCellListBoxItemDrawer_Reserved() |
|
1344 { |
|
1345 } |
|
1346 |
|
1347 void CFormattedCellListBoxItemDrawer::DrawBackgroundAndSeparatorLines( const TRect& aItemTextRect ) const |
|
1348 { |
|
1349 MAknsSkinInstance *skin = AknsUtils::SkinInstance(); |
|
1350 CCoeControl* control = FormattedCellData()->Control(); |
|
1351 MAknsControlContext *cc = AknsDrawUtils::ControlContext( control ); |
|
1352 |
|
1353 if ( !cc ) |
|
1354 { |
|
1355 cc = FormattedCellData()->SkinBackgroundContext(); |
|
1356 } |
|
1357 |
|
1358 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1359 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
1360 |
|
1361 if ( transApi && !transApi->EffectsDisabled() ) |
|
1362 { |
|
1363 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iGc ); |
|
1364 |
|
1365 if ( tfxApi ) |
|
1366 { |
|
1367 tfxApi->EnableEffects( FormattedCellData()->IsBackgroundDrawingEnabled() ); |
|
1368 } |
|
1369 } |
|
1370 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
1371 |
|
1372 // background |
|
1373 if ( FormattedCellData()->IsBackgroundDrawingEnabled() ) |
|
1374 { |
|
1375 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1376 MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc ); |
|
1377 if ( transApi ) |
|
1378 { |
|
1379 transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); |
|
1380 } |
|
1381 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
1382 TBool bgDrawn( EFalse ); |
|
1383 if ( control ) |
|
1384 { |
|
1385 const MCoeControlBackground* backgroundDrawer = |
|
1386 control->FindBackground(); |
|
1387 |
|
1388 if ( backgroundDrawer ) |
|
1389 { |
|
1390 backgroundDrawer->Draw( *iGc, *control, aItemTextRect ); |
|
1391 bgDrawn = ETrue; |
|
1392 } |
|
1393 else if ( CAknEnv::Static()->TransparencyEnabled() ) |
|
1394 { |
|
1395 bgDrawn = AknsDrawUtils::Background( |
|
1396 skin, cc, control, *iGc, aItemTextRect, |
|
1397 KAknsDrawParamNoClearUnderImage ); |
|
1398 } |
|
1399 else |
|
1400 { |
|
1401 bgDrawn = AknsDrawUtils::Background( |
|
1402 skin, cc, control, *iGc, aItemTextRect, |
|
1403 KAknsDrawParamNoClearUnderImage | |
|
1404 KAknsDrawParamBottomLevelRGBOnly ); |
|
1405 } |
|
1406 } |
|
1407 if ( !bgDrawn ) |
|
1408 { |
|
1409 iGc->Clear( aItemTextRect ); |
|
1410 } |
|
1411 #ifdef RD_UI_TRANSITION_EFFECTS_LIST |
|
1412 if ( transApi ) |
|
1413 { |
|
1414 transApi->StopDrawing(); |
|
1415 } |
|
1416 #endif // RD_UI_TRANSITION_EFFECTS_LIST |
|
1417 } |
|
1418 } |
|
1419 |
|
1420 // End of File |