|
1 /* |
|
2 * Copyright (c) 2002 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: ListBox View class. The class has a special drawing and |
|
15 * special cusor moving. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 //debug |
|
22 #include "calendarui_debug.h" |
|
23 |
|
24 |
|
25 // INCLUDE FILES |
|
26 #include "calendaylistboxview.h" |
|
27 #include "CalendarVariant.hrh" |
|
28 #include "calendrawutils.h" |
|
29 |
|
30 #include <AknUtils.h> |
|
31 #include <AknsDrawUtils.h> |
|
32 #include <AknsEffectAnim.h> |
|
33 #include <eikfrlbd.h> |
|
34 |
|
35 #include <aknlayoutscalable_apps.cdl.h> |
|
36 #include <aknlayoutscalable_avkon.cdl.h> |
|
37 |
|
38 |
|
39 const TInt KMaxLineInACell(4); |
|
40 |
|
41 #define ITEM_EXISTS_ONCE(x) (((x) > -1) && ((x) < iModel->NumberOfItems())) |
|
42 |
|
43 // ================= MEMBER FUNCTIONS ======================= |
|
44 |
|
45 CCalenDayListBoxView::CCalenDayListBoxView(CCoeControl* aParent) |
|
46 : iParent(aParent) |
|
47 { |
|
48 TRACE_ENTRY_POINT; |
|
49 TRACE_EXIT_POINT; |
|
50 } |
|
51 |
|
52 CCalenDayListBoxView::~CCalenDayListBoxView() |
|
53 { |
|
54 TRACE_ENTRY_POINT; |
|
55 |
|
56 delete iCellArray; |
|
57 |
|
58 TRACE_EXIT_POINT; |
|
59 } |
|
60 |
|
61 // ---------------------------------------------------- |
|
62 // CCalenDayListBoxView::SetCellArray |
|
63 // Sets a array for dividing a cell |
|
64 // (other items were commented in a header). |
|
65 // ---------------------------------------------------- |
|
66 // |
|
67 void CCalenDayListBoxView::SetCellArray(CArrayFix<TInt>* aArray) |
|
68 { |
|
69 TRACE_ENTRY_POINT; |
|
70 |
|
71 delete iCellArray; |
|
72 iCellArray = aArray; |
|
73 |
|
74 TRACE_EXIT_POINT; |
|
75 } |
|
76 |
|
77 TInt CCalenDayListBoxView::FirstLineOfCell(TInt aLine) const |
|
78 { |
|
79 TRACE_ENTRY_POINT; |
|
80 |
|
81 for (TInt i = aLine; i >= 0; i--) |
|
82 { |
|
83 if (IsFirstLineOfCell(i)) |
|
84 { |
|
85 return i; |
|
86 } |
|
87 } |
|
88 |
|
89 TRACE_EXIT_POINT; |
|
90 return aLine; // FIXME, should not get here. |
|
91 } |
|
92 |
|
93 TInt CCalenDayListBoxView::LastLineOfCell(TInt aLine) const |
|
94 { |
|
95 TRACE_ENTRY_POINT; |
|
96 |
|
97 for (TInt i = aLine; i < iModel->NumberOfItems(); ++i) |
|
98 { |
|
99 if (IsLastLineOfCell(i)) |
|
100 { |
|
101 return i; |
|
102 } |
|
103 } |
|
104 |
|
105 TRACE_EXIT_POINT; |
|
106 return aLine; // FIXME, should not get here |
|
107 } |
|
108 |
|
109 // ---------------------------------------------------- |
|
110 // CCalenDayListBoxView::IsLastLineOfCell |
|
111 // |
|
112 // (other items were commented in a header). |
|
113 // ---------------------------------------------------- |
|
114 // |
|
115 TBool CCalenDayListBoxView::IsLastLineOfCell(TInt aLine) const |
|
116 { |
|
117 TRACE_ENTRY_POINT; |
|
118 |
|
119 TKeyArrayFix key(0, ECmpTInt32); |
|
120 TInt index(0); |
|
121 TBool retValue(EFalse); |
|
122 if (iCellArray->FindIsq(aLine, key, index) == 0) |
|
123 { |
|
124 retValue = ETrue; |
|
125 } |
|
126 |
|
127 TRACE_EXIT_POINT; |
|
128 return retValue; |
|
129 } |
|
130 |
|
131 // ---------------------------------------------------- |
|
132 // CCalenDayListBoxView::IsFirstLineOfCell |
|
133 // |
|
134 // (other items were commented in a header). |
|
135 // ---------------------------------------------------- |
|
136 // |
|
137 TBool CCalenDayListBoxView::IsFirstLineOfCell(TInt aLine) const |
|
138 { |
|
139 TRACE_ENTRY_POINT; |
|
140 |
|
141 TKeyArrayFix key(0, ECmpTInt32); |
|
142 TInt index(0); |
|
143 TBool retValue(EFalse); |
|
144 if (aLine == 0) |
|
145 { |
|
146 retValue = ETrue; |
|
147 } |
|
148 else if (iCellArray->FindIsq(aLine -1, key, index) == 0) |
|
149 { |
|
150 retValue = ETrue; |
|
151 } |
|
152 |
|
153 TRACE_EXIT_POINT; |
|
154 return retValue; |
|
155 } |
|
156 |
|
157 // ---------------------------------------------------- |
|
158 // CCalenDayListBoxView::DrawCell |
|
159 // |
|
160 // (other items were commented in a header). |
|
161 // ---------------------------------------------------- |
|
162 // |
|
163 void CCalenDayListBoxView::DrawCell(TInt aIndex) |
|
164 { |
|
165 TRACE_ENTRY_POINT; |
|
166 |
|
167 TInt lastLine(LastLineOfCell(aIndex)); |
|
168 for (TInt i(aIndex); i <= lastLine; ++i) |
|
169 { |
|
170 DrawItem(i); |
|
171 } |
|
172 |
|
173 TRACE_EXIT_POINT; |
|
174 } |
|
175 |
|
176 // ---------------------------------------------------- |
|
177 // |
|
178 // ---------------------------------------------------- |
|
179 // |
|
180 TRect CCalenDayListBoxView::DayViewItemRect(TInt aItemIndex) const |
|
181 { |
|
182 TRACE_ENTRY_POINT; |
|
183 |
|
184 TInt topLine(FirstLineOfCell(aItemIndex)); |
|
185 TInt bottomLine(LastLineOfCell(aItemIndex)); |
|
186 |
|
187 //topLine = topLine > iTopItemIndex ? topLine : iTopItemIndex; |
|
188 |
|
189 bottomLine = bottomLine > iBottomItemIndex ? iBottomItemIndex : bottomLine; |
|
190 TRect rectHighlight(ItemPos(topLine), ItemPos(bottomLine)); |
|
191 rectHighlight.iBr += CListBoxView::ItemSize(bottomLine); |
|
192 |
|
193 TRACE_EXIT_POINT; |
|
194 return rectHighlight; |
|
195 } |
|
196 |
|
197 // ---------------------------------------------------- |
|
198 // CCalenDayListBoxView::ItemSize |
|
199 // |
|
200 // (other items were commented in a header). |
|
201 // ---------------------------------------------------- |
|
202 // |
|
203 TSize CCalenDayListBoxView::ItemSize(TInt aItemIndex) const |
|
204 { |
|
205 TRACE_ENTRY_POINT; |
|
206 TRACE_EXIT_POINT; |
|
207 return DayViewItemRect(aItemIndex).Size(); |
|
208 } |
|
209 |
|
210 void CCalenDayListBoxView::DrawItem(TInt aItemIndex) const |
|
211 { |
|
212 TRACE_ENTRY_POINT; |
|
213 |
|
214 PIM_TRAPD_HANDLE(DrawItemL(aItemIndex)); |
|
215 |
|
216 TRACE_ENTRY_POINT; |
|
217 } |
|
218 |
|
219 void CCalenDayListBoxView::DrawItemL(TInt aItemIndex) const |
|
220 { |
|
221 TRACE_ENTRY_POINT; |
|
222 |
|
223 // FIXME: this function needs cleanup. |
|
224 if(RedrawDisabled() || !IsVisible()) |
|
225 { |
|
226 return; |
|
227 } |
|
228 |
|
229 if((ITEM_EXISTS_ONCE(aItemIndex)) && ItemIsVisible(aItemIndex)) |
|
230 { |
|
231 TBool highlight(EFalse); |
|
232 if(aItemIndex >= iCurrentItemIndex && aItemIndex < iCurrentItemIndex + KMaxLineInACell) |
|
233 { |
|
234 TInt nextCell(LastLineOfCell(iCurrentItemIndex) + 1); |
|
235 |
|
236 if ( !( iItemDrawer->Flags() |
|
237 & CTextListItemDrawer::EDisableHighlight ) |
|
238 && aItemIndex < nextCell ) |
|
239 { |
|
240 highlight = ETrue; |
|
241 } |
|
242 } |
|
243 TBool hlDone( EFalse ); |
|
244 TBool animHLDone( EFalse ); |
|
245 |
|
246 MAknsSkinInstance *skin = AknsUtils::SkinInstance(); |
|
247 CFormattedCellListBoxData* data = static_cast<CFormattedCellListBoxItemDrawer*>(iItemDrawer)->FormattedCellData(); |
|
248 |
|
249 // Skinned highlight |
|
250 if( ( highlight && IsFirstLineOfCell( aItemIndex ) ) ||(highlight && aItemIndex == iTopItemIndex)) |
|
251 { |
|
252 MAknsControlContext *cc = AknsDrawUtils::ControlContext( iParent ); |
|
253 |
|
254 if(!cc) |
|
255 { |
|
256 cc = static_cast<CFormattedCellListBoxItemDrawer*>(iItemDrawer)->FormattedCellData()->SkinBackgroundContext(); |
|
257 } |
|
258 |
|
259 TRect dayViewItemRect( DayViewItemRect( aItemIndex ) ); |
|
260 TAknLayoutRect list_highlight_pane_cp1; |
|
261 list_highlight_pane_cp1.LayoutRect( dayViewItemRect, AknLayoutScalable_Avkon::list_highlight_pane_cp1().LayoutLine() ); |
|
262 |
|
263 if( data->HighlightAnim() && data ) |
|
264 { |
|
265 data->SetItemCellSize( dayViewItemRect.Size() ); // ??? |
|
266 data->AboutToDrawHighlightAnim(); |
|
267 if( data->HighlightAnim() ) |
|
268 hlDone = data->HighlightAnim()->Render( *iGc, list_highlight_pane_cp1.Rect() ); |
|
269 animHLDone = hlDone; |
|
270 } |
|
271 |
|
272 // Either animation does not exist or drawing it failed |
|
273 if( !hlDone ) |
|
274 { |
|
275 if( cc ) |
|
276 { |
|
277 AknsDrawUtils::Background( skin, cc, iParent, *iGc, dayViewItemRect); //??? Isn't it this drawn already? |
|
278 } |
|
279 |
|
280 iGc->SetPenStyle(CGraphicsContext::ENullPen); |
|
281 |
|
282 // Skin Center layout |
|
283 TAknLayoutRect list_highlight_pane_g1_cp1; |
|
284 list_highlight_pane_g1_cp1.LayoutRect( list_highlight_pane_cp1.Rect(), AknLayoutScalable_Avkon::list_highlight_pane_g1_cp1().LayoutLine() ); |
|
285 |
|
286 hlDone = AknsDrawUtils::DrawFrame(skin, *iGc, |
|
287 list_highlight_pane_cp1.Rect(), // whole highlight rect |
|
288 list_highlight_pane_g1_cp1.Rect(), // skin center rect |
|
289 KAknsIIDQsnFrList, KAknsIIDQsnFrListCenter); |
|
290 } |
|
291 } |
|
292 |
|
293 TBool skinFlg(data->SkinEnabled()); |
|
294 |
|
295 iGc->SetDrawMode(CGraphicsContext::EDrawModePEN); |
|
296 |
|
297 // FIXME: investigate if this is really needed |
|
298 if(highlight) |
|
299 { |
|
300 //iGc->SetDrawMode( CGraphicsContext::EDrawModeAND ); |
|
301 data->SetSkinEnabledL( EFalse ); |
|
302 } |
|
303 TRect rect( ItemPos( aItemIndex ), CListBoxView::ItemSize( aItemIndex ) ); |
|
304 |
|
305 // Non-highlighted cell skin background |
|
306 if(!highlight && iParent) |
|
307 { |
|
308 MAknsControlContext *cc = AknsDrawUtils::ControlContext(iParent); |
|
309 if(!cc) |
|
310 { |
|
311 cc = static_cast<CFormattedCellListBoxItemDrawer*>(iItemDrawer)->FormattedCellData()->SkinBackgroundContext(); |
|
312 } |
|
313 |
|
314 if(cc) |
|
315 { |
|
316 AknsDrawUtils::Background( skin, cc, iParent, *iGc, rect); |
|
317 } |
|
318 } |
|
319 |
|
320 // Text and graphic content |
|
321 iItemDrawer->DrawItem(aItemIndex, ItemPos(aItemIndex), ItemIsSelected(aItemIndex), highlight, 0, 0 ); |
|
322 |
|
323 // if the highlight is animated we need to redraw all lines of a multi-line item |
|
324 if( animHLDone ) |
|
325 { |
|
326 TInt index( aItemIndex ); |
|
327 while( !IsLastLineOfCell( index ) ) |
|
328 { |
|
329 if( ItemIsVisible( ++index ) ) |
|
330 { |
|
331 iItemDrawer->DrawItem( index, ItemPos( index ), ItemIsSelected( index ), highlight, 0, 0 ); |
|
332 } |
|
333 } |
|
334 } |
|
335 |
|
336 iGc->SetDrawMode( CGraphicsContext::EDrawModePEN ); |
|
337 data->SetSkinEnabledL( skinFlg ); |
|
338 |
|
339 // Line between cells |
|
340 if( IsLastLineOfCell(aItemIndex) && !highlight ) |
|
341 { |
|
342 // Get line color |
|
343 TRgb lineColor(0,0,0); |
|
344 AknsUtils::GetCachedColor(AknsUtils::SkinInstance(), lineColor, |
|
345 KAknsIIDQsnLineColors, |
|
346 EAknsCIQsnLineColorsCG2); |
|
347 iGc->SetPenColor( lineColor ); |
|
348 iGc->SetBrushColor( lineColor ); |
|
349 iGc->SetPenStyle(CGraphicsContext::ESolidPen); |
|
350 iGc->SetBrushStyle(CGraphicsContext::ENullBrush); |
|
351 |
|
352 // Draw line. There is graphic item qgn_graf_line_cale_day defined for line, but using it would require |
|
353 // caching it first. To be done later? |
|
354 #ifndef RD_CALEN_MIDNIGHT_VISUALIZATION |
|
355 TInt variety_g2 = 0; // We don't care about variety, because separator line definition is same for all |
|
356 #else |
|
357 TInt variety_g2(-1); |
|
358 TInt countryCode( User::Language() ); |
|
359 TLocale locale; |
|
360 locale.Refresh(); |
|
361 TTimeFormat timeFormat( locale.TimeFormat() ); |
|
362 |
|
363 if( timeFormat == ETime24 ) |
|
364 { |
|
365 // Option 1: 24 hour |
|
366 variety_g2 = 0; |
|
367 } |
|
368 // 12 hour |
|
369 else if( countryCode == ELangCzech ) |
|
370 { |
|
371 // Option 3: Czech, 12 hour with Arrow |
|
372 variety_g2 = 8; |
|
373 } |
|
374 else |
|
375 { |
|
376 // Option 15: 12 hour, with Arrow |
|
377 variety_g2 = 7; |
|
378 } |
|
379 |
|
380 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION |
|
381 |
|
382 TAknLayoutRect list_cale_time_pane_g2; |
|
383 list_cale_time_pane_g2.LayoutRect( rect, AknLayoutScalable_Apps::list_cale_time_pane_g2( variety_g2 ).LayoutLine() ); |
|
384 iGc->DrawRect( list_cale_time_pane_g2.Rect() ); |
|
385 } |
|
386 } |
|
387 |
|
388 TRACE_EXIT_POINT; |
|
389 } |
|
390 |
|
391 // ---------------------------------------------------- |
|
392 // |
|
393 // ---------------------------------------------------- |
|
394 // |
|
395 void CCalenDayListBoxView::ScrollToItemL(TInt aItemIndex, TSelectionMode aSelectionMode) |
|
396 { |
|
397 TRACE_ENTRY_POINT; |
|
398 |
|
399 TInt oldItemIndex = iCurrentItemIndex; |
|
400 TInt oldTopIndex = iTopItemIndex; |
|
401 |
|
402 // To prevent incorrect drawing and flickering, we just move focus |
|
403 // without updating the screen. Uikon list can't draw correct multirow |
|
404 // focus for us |
|
405 // Updating is done below. |
|
406 VerticalMoveToItemL(aItemIndex, aSelectionMode); |
|
407 |
|
408 //These two scrolls ensure that all lines of item are visible. |
|
409 //If list is scrolled, it is correctly updated and drawn by these methods |
|
410 ScrollToMakeItemVisible( FirstLineOfCell(aItemIndex) ); |
|
411 ScrollToMakeItemVisible( LastLineOfCell(aItemIndex) ); |
|
412 |
|
413 // If list was not scrolled, we update old focus cell and new focus cell. |
|
414 if (oldTopIndex == iTopItemIndex) |
|
415 { |
|
416 if (oldItemIndex != iCurrentItemIndex) |
|
417 { |
|
418 DrawCell(oldItemIndex); |
|
419 DrawCell(iCurrentItemIndex); |
|
420 } |
|
421 } |
|
422 |
|
423 TRACE_EXIT_POINT; |
|
424 } |
|
425 |
|
426 // ---------------------------------------------------- |
|
427 // CCalenDayListBoxView::MoveCursorL |
|
428 // |
|
429 // (other items were commented in a header). |
|
430 // ---------------------------------------------------- |
|
431 // |
|
432 void CCalenDayListBoxView::MoveCursorL( |
|
433 TCursorMovement aCursorMovement, TSelectionMode aSelectionMode) |
|
434 { |
|
435 TRACE_ENTRY_POINT; |
|
436 |
|
437 switch (aCursorMovement) |
|
438 { |
|
439 case CListBoxView::ECursorPreviousItem: |
|
440 { |
|
441 TInt prevLine(iCurrentItemIndex - 1); |
|
442 if (prevLine >= 0) |
|
443 { |
|
444 TInt topLine = FirstLineOfCell(prevLine); |
|
445 ScrollToItemL(topLine, aSelectionMode); |
|
446 } |
|
447 break; |
|
448 } |
|
449 case CListBoxView::ECursorNextItem: |
|
450 { |
|
451 TInt nextCell = LastLineOfCell(iCurrentItemIndex) + 1; |
|
452 if (nextCell < iModel->NumberOfItems()) |
|
453 { |
|
454 ScrollToItemL(nextCell, aSelectionMode); |
|
455 } |
|
456 break; |
|
457 } |
|
458 case CListBoxView::ECursorFirstItem: |
|
459 { |
|
460 TInt firstItem = 0; |
|
461 if ( firstItem != iCurrentItemIndex) |
|
462 { |
|
463 ScrollToItemL(firstItem, aSelectionMode); |
|
464 } |
|
465 break; |
|
466 } |
|
467 case CListBoxView::ECursorLastItem: |
|
468 { |
|
469 TInt lastLine = iModel->NumberOfItems() - 1; |
|
470 TInt lastItem = FirstLineOfCell(lastLine); |
|
471 if ( lastItem != iCurrentItemIndex) |
|
472 { |
|
473 ScrollToItemL(lastItem, aSelectionMode); |
|
474 } |
|
475 break; |
|
476 } |
|
477 default: |
|
478 { |
|
479 // Other TCursorMovements are not implemented. |
|
480 // Calling superclass's function would not work |
|
481 break; |
|
482 } |
|
483 } |
|
484 |
|
485 TRACE_EXIT_POINT; |
|
486 } |
|
487 |
|
488 |
|
489 // ---------------------------------------------------- |
|
490 // CCalenDayListBoxView::MoveToItemL |
|
491 // Move to new event (from touch) |
|
492 // (other items were commented in a header). |
|
493 // ---------------------------------------------------- |
|
494 // |
|
495 void CCalenDayListBoxView::MoveToItemL(TInt aItemIndex) |
|
496 { |
|
497 TRACE_ENTRY_POINT; |
|
498 |
|
499 if(AknLayoutUtils::PenEnabled()) |
|
500 { |
|
501 TInt oldItemIndex = FirstLineOfCell(iCurrentItemIndex); |
|
502 TInt oldTopIndex = iTopItemIndex; |
|
503 |
|
504 // To prevent incorrect drawing and flickering, we just move focus |
|
505 // without updating the screen. Uikon list can't draw correct multirow |
|
506 // focus for us |
|
507 // Updating is done below. |
|
508 SetDisableRedraw(ETrue); |
|
509 VerticalMoveToItemL(FirstLineOfCell(aItemIndex), CListBoxView::ENoSelection); |
|
510 SetDisableRedraw(EFalse); |
|
511 |
|
512 //These two scrolls ensure that all lines of item are visible. |
|
513 //If list is scrolled, it is correctly updated and drawn by these methods |
|
514 ScrollToMakeItemVisible( FirstLineOfCell(aItemIndex) ); |
|
515 ScrollToMakeItemVisible( LastLineOfCell(aItemIndex) ); |
|
516 |
|
517 // If list was not scrolled, we update old focus cell and new focus cell. |
|
518 if (oldTopIndex == iTopItemIndex) |
|
519 { |
|
520 if (oldItemIndex != FirstLineOfCell(iCurrentItemIndex)) |
|
521 { |
|
522 DrawCell(oldItemIndex); |
|
523 DrawCell(FirstLineOfCell(iCurrentItemIndex)); |
|
524 } |
|
525 } |
|
526 } |
|
527 |
|
528 TRACE_EXIT_POINT; |
|
529 } |
|
530 |
|
531 |
|
532 // End of File |