|
1 /* |
|
2 * Copyright (c) 2002-2010 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: LandmarksUi Content File - Landmarks icon selector map |
|
15 * |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include <eikenv.h> |
|
20 #include <eiksbfrm.h> |
|
21 #include <eikscrlb.h> |
|
22 #include <bidivisual.h> |
|
23 #include <avkon.rsg> |
|
24 #include <AknPanic.h> |
|
25 #include <avkon.hrh> |
|
26 #include <AknUtils.h> |
|
27 #include <aknlayoutscalable_avkon.cdl.h> |
|
28 #include <layoutmetadata.cdl.h> |
|
29 #include <AknLayout.lag> |
|
30 |
|
31 #include <aknappui.h> |
|
32 #include <aknconsts.h> |
|
33 #include <AknDef.h> |
|
34 #include <PUAcodes.hrh> |
|
35 #include <s32file.h> |
|
36 |
|
37 #ifdef RD_TACTILE_FEEDBACK |
|
38 #include <touchfeedback.h> |
|
39 #endif //RD_TACTILE_FEEDBACK |
|
40 // For the TEikScrollBarModelType |
|
41 #include <eikscrlb.h> |
|
42 |
|
43 #include <AknsDrawUtils.h> |
|
44 #include <featmgr.h> |
|
45 |
|
46 #include <AknsFrameBackgroundControlContext.h> |
|
47 |
|
48 #include <lmkui.mbg> |
|
49 |
|
50 #include "lmkiconmap.h" |
|
51 #include "CLmkUiUtils.h" |
|
52 #include <lmkerrors.h> |
|
53 |
|
54 // The offset because of CEikDialogPage |
|
55 const TInt KHorizontalDialogMargin = 0; |
|
56 const TInt KVerticalDialogMargin = 0; |
|
57 const TInt KAknSctCBaButtonDirections = 3; // bottom, right and left |
|
58 |
|
59 |
|
60 /// Unnamed namespace for local definitions |
|
61 namespace |
|
62 { |
|
63 const TInt KNumOfIcons(16); |
|
64 _LIT( KPanicMsg, "CLmkIconMap" ); |
|
65 |
|
66 void Panic(TPanicCode aReason) |
|
67 { |
|
68 User::Panic(KPanicMsg, aReason); |
|
69 } |
|
70 } // namespace |
|
71 |
|
72 // ============================ EXTENSION CLASS =============================== |
|
73 //Class Declaration |
|
74 NONSHARABLE_CLASS(CLmkIconMapExtension) : public CBase, |
|
75 public MObjectProvider |
|
76 { |
|
77 public: |
|
78 CLmkIconMapExtension(); |
|
79 ~CLmkIconMapExtension(); |
|
80 |
|
81 protected: |
|
82 TTypeUid::Ptr MopSupplyObject(TTypeUid aId); |
|
83 MObjectProvider* MopNext(); |
|
84 |
|
85 public: |
|
86 // data |
|
87 MCoeControlObserver *iObserver; |
|
88 |
|
89 TUint iFlags; |
|
90 MObjectProvider* iIconMap; |
|
91 TInt iMaxVisibleRows; |
|
92 CAknsFrameBackgroundControlContext* iBgContext; |
|
93 }; |
|
94 |
|
95 // ============================ MEMBER FUNCTIONS OF CLmkIconMapExtension =============================== |
|
96 |
|
97 // ----------------------------------------------------------------------------- |
|
98 // CLmkIconMapExtension::CLmkIconMapExtension |
|
99 // C++ default constructor can NOT contain any code, that |
|
100 // might leave. |
|
101 // ----------------------------------------------------------------------------- |
|
102 // |
|
103 CLmkIconMapExtension::CLmkIconMapExtension() : |
|
104 iMaxVisibleRows(0) |
|
105 { |
|
106 iObserver = NULL; |
|
107 } |
|
108 |
|
109 // ----------------------------------------------------------------------------- |
|
110 // CLmkIconMapExtension::MopSupplyObject() |
|
111 // ----------------------------------------------------------------------------- |
|
112 // |
|
113 TTypeUid::Ptr CLmkIconMapExtension::MopSupplyObject(TTypeUid aId) |
|
114 { |
|
115 return MAknsControlContext::SupplyMopObject(aId, iBgContext); |
|
116 } |
|
117 |
|
118 // ----------------------------------------------------------------------------- |
|
119 // CLmkIconMapExtension::MopNext() |
|
120 // ----------------------------------------------------------------------------- |
|
121 // |
|
122 MObjectProvider* CLmkIconMapExtension::MopNext() |
|
123 { |
|
124 return iIconMap; |
|
125 } |
|
126 |
|
127 // ----------------------------------------------------------------------------- |
|
128 // CLmkIconMapExtension::~CLmkIconMapExtension() |
|
129 // ----------------------------------------------------------------------------- |
|
130 // |
|
131 CLmkIconMapExtension::~CLmkIconMapExtension() |
|
132 { |
|
133 |
|
134 delete iBgContext; |
|
135 } |
|
136 |
|
137 // ============================ MEMBER FUNCTIONS OF CLmkIconMap =============================== |
|
138 |
|
139 // ----------------------------------------------------------------------------- |
|
140 // CLmkIconMap::CLmkIconMap |
|
141 // C++ default constructor can NOT contain any code, that |
|
142 // might leave. |
|
143 // ----------------------------------------------------------------------------- |
|
144 // |
|
145 CLmkIconMap::CLmkIconMap() : |
|
146 iCursorPos(TPoint(0, 0)), iOldCursorPos(TPoint(0, 0)), iMaxColumns(-1), |
|
147 iCurrentPage(0), iNumPages(0) |
|
148 { |
|
149 iConsArray = (CArrayPtr<CGulIcon>*) NULL; |
|
150 } |
|
151 |
|
152 // ----------------------------------------------------------------------------- |
|
153 // CLmkIconMap::NewL |
|
154 // Two-phased constructor. |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 CLmkIconMap* CLmkIconMap::NewL() |
|
158 { |
|
159 CLmkIconMap* self = new (ELeave) CLmkIconMap(); |
|
160 |
|
161 CleanupStack::PushL(self); |
|
162 self->ConstructL(); |
|
163 CleanupStack::Pop(self); //self |
|
164 return self; |
|
165 } |
|
166 |
|
167 // ----------------------------------------------------------------------------- |
|
168 // CLmkIconMap::ConstructL |
|
169 // Symbian 2nd phase constructor can leave. |
|
170 // ----------------------------------------------------------------------------- |
|
171 // |
|
172 void CLmkIconMap::ConstructL() |
|
173 { |
|
174 // Must be created here to get the member variables available |
|
175 iExtension = new (ELeave) CLmkIconMapExtension; |
|
176 iExtension->iIconMap = this; |
|
177 |
|
178 iConsArray = new (ELeave) CAknIconArray(KNumOfIcons); |
|
179 |
|
180 iExtension->iFlags = 0x00; |
|
181 |
|
182 DoLayout(); |
|
183 } |
|
184 |
|
185 // ----------------------------------------------------------------------------- |
|
186 // CLmkIconMap::~CLmkIconMap() |
|
187 // ----------------------------------------------------------------------------- |
|
188 // |
|
189 CLmkIconMap::~CLmkIconMap() |
|
190 { |
|
191 delete iSBFrame; |
|
192 iSBFrame = (CEikScrollBarFrame*) NULL; |
|
193 |
|
194 delete iOffscreenBg; |
|
195 delete iBitmapDevice; |
|
196 delete iBitmapGc; |
|
197 |
|
198 delete iExtension; |
|
199 iExtension = (CLmkIconMapExtension*) NULL; |
|
200 |
|
201 if (iConsArray) |
|
202 { |
|
203 iConsArray->ResetAndDestroy(); |
|
204 delete iConsArray; |
|
205 iConsArray = (CArrayPtr<CGulIcon>*) NULL; |
|
206 } |
|
207 } |
|
208 |
|
209 // ----------------------------------------------------------------------------- |
|
210 // CLmkIconMap::DoLayout() |
|
211 // ----------------------------------------------------------------------------- |
|
212 // |
|
213 void CLmkIconMap::DoLayout() |
|
214 { |
|
215 TRAPD(err, LoadIconL()); |
|
216 if (err) |
|
217 return; |
|
218 |
|
219 iIsMirrored = AknLayoutUtils::LayoutMirrored(); |
|
220 iDrawnBefore = EFalse; |
|
221 CountMaxColumnsAndCellSizes(); |
|
222 SizeChanged(); |
|
223 } |
|
224 |
|
225 // ----------------------------------------------------------------------------- |
|
226 // CLmkIconMap::ConstructFromResourceL() |
|
227 // ----------------------------------------------------------------------------- |
|
228 // |
|
229 void CLmkIconMap::ConstructFromResourceL(TResourceReader& /*aReader*/) |
|
230 { |
|
231 LoadIconL(); |
|
232 CreateScrollBarAndIconRowL(); |
|
233 |
|
234 Extension()->iBgContext = CAknsFrameBackgroundControlContext::NewL( |
|
235 KAknsIIDQsnFrPopup, TRect(0, 0, 1, 1), TRect(0, 0, 1, 1), EFalse); |
|
236 |
|
237 if (DrawableWindow() && AknLayoutUtils::PenEnabled()) |
|
238 { |
|
239 EnableDragEvents(); |
|
240 SetGloballyCapturing( ETrue); |
|
241 SetPointerCapture(ETrue); |
|
242 } |
|
243 } |
|
244 |
|
245 // ----------------------------------------------------------------------------- |
|
246 // CLmkIconMap::LoadIcons() |
|
247 // This actually load the all icons to be shown on dialog from icon file |
|
248 // ----------------------------------------------------------------------------- |
|
249 // |
|
250 void CLmkIconMap::LoadIconL() |
|
251 { |
|
252 if (iConsArray) |
|
253 { |
|
254 iConsArray->ResetAndDestroy(); |
|
255 } |
|
256 // Draw all the Icons. |
|
257 TFileName* iconFile = CLmkUiUtils::LmkUiIconFileLC(); |
|
258 |
|
259 // Create icon bitmap and mask. |
|
260 for (TInt i(0); i < (KNumOfIcons * 2); i++) |
|
261 { |
|
262 CFbsBitmap* bitmap = NULL; |
|
263 CFbsBitmap* bitmapMask = NULL; |
|
264 AknIconUtils::CreateIconLC(bitmap, bitmapMask, *iconFile, |
|
265 EMbmLmkuiQgn_prop_lm_transport + i, |
|
266 EMbmLmkuiQgn_prop_lm_transport + i + 1); |
|
267 i++; |
|
268 AknIconUtils::SetSize(bitmap, TSize(iGridItemWidth, iGridItemHeight)); //fix |
|
269 AknIconUtils::SetSize(bitmapMask, TSize(iGridItemWidth, |
|
270 iGridItemHeight)); //fix |
|
271 CGulIcon* icon = CGulIcon::NewL(bitmap, bitmapMask); |
|
272 CleanupStack::PushL(icon); |
|
273 if (iConsArray) |
|
274 iConsArray->AppendL(icon); |
|
275 CleanupStack::Pop(icon); // icon |
|
276 CleanupStack::Pop(bitmapMask); // mask |
|
277 CleanupStack::Pop(bitmap); // bitmap |
|
278 } |
|
279 CleanupStack::PopAndDestroy();// iconFile |
|
280 } |
|
281 |
|
282 // ----------------------------------------------------------------------------- |
|
283 // CLmkIconMap::HeightInRows() |
|
284 // This actually returns the no of rows to be shown on a page |
|
285 // Depends upon the Layout size |
|
286 // ----------------------------------------------------------------------------- |
|
287 // |
|
288 TInt CLmkIconMap::HeightInRows() |
|
289 { |
|
290 return (iRows); |
|
291 } |
|
292 |
|
293 // ----------------------------------------------------------------------------- |
|
294 // CLmkIconMap::CreateScrollBarAndIconRowL() |
|
295 // This actually creates the scroll bar sets the number of |
|
296 // pages and rows on a page to be shown |
|
297 // ----------------------------------------------------------------------------- |
|
298 // |
|
299 void CLmkIconMap::CreateScrollBarAndIconRowL() |
|
300 { |
|
301 __ASSERT_DEBUG(iExtension, Panic(KLmkPanicInvalidResourceData)); |
|
302 |
|
303 __ASSERT_ALWAYS(iConsArray, Panic(KLmkPanicInvalidResourceData)); |
|
304 |
|
305 iRows = ((iConsArray->Count() - 1) / iMaxColumns) + 1; |
|
306 iFirstVisibleRow = 0; |
|
307 iAnimated = EFalse; |
|
308 iCursorPos = TPoint(0, 0); |
|
309 iNumPages = (iRows / iExtension->iMaxVisibleRows) + (iRows |
|
310 % iExtension->iMaxVisibleRows ? 1 : 0); |
|
311 iCurrentPage = 1; |
|
312 |
|
313 // Create and set the scb visible even though there is nothing to scroll |
|
314 delete iSBFrame; |
|
315 iSBFrame = NULL; |
|
316 |
|
317 if (AknLayoutUtils::PenEnabled()) |
|
318 { |
|
319 iSBFrame = new (ELeave) CEikScrollBarFrame(this, this, ETrue); |
|
320 } |
|
321 else |
|
322 { |
|
323 iSBFrame = new (ELeave) CEikScrollBarFrame(this, NULL, ETrue); |
|
324 } |
|
325 // Decide which type of scrollbar is shown |
|
326 CAknAppUi* appUi = iAvkonAppUi; |
|
327 if (AknLayoutUtils::DefaultScrollBarType(appUi) |
|
328 == CEikScrollBarFrame::EDoubleSpan) |
|
329 { |
|
330 // For EDoubleSpan type scrollbar |
|
331 if (AknLayoutUtils::PenEnabled()) |
|
332 { |
|
333 iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse, ETrue, |
|
334 EFalse); // window owning scrollbar |
|
335 } |
|
336 else |
|
337 { |
|
338 iSBFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue, |
|
339 EFalse); // non-window owning scrollbar |
|
340 } |
|
341 iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EDoubleSpan); |
|
342 } |
|
343 else |
|
344 { |
|
345 // For EArrowHead type scrollbar |
|
346 iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EArrowHead); |
|
347 } |
|
348 |
|
349 iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, |
|
350 CEikScrollBarFrame::EAuto); |
|
351 iSBFrame->VerticalScrollBar()->SetMopParent(iExtension); |
|
352 UpdateScrollIndicatorL(); |
|
353 } |
|
354 |
|
355 // ----------------------------------------------------------------------------- |
|
356 // CLmkIconMap::SetIndex |
|
357 // set the reference of the selected icon index from the table |
|
358 // ----------------------------------------------------------------------------- |
|
359 // |
|
360 void CLmkIconMap::SetIndex(TInt& aIconIndex) |
|
361 { |
|
362 iIconIndex = &aIconIndex; |
|
363 } |
|
364 |
|
365 // ----------------------------------------------------------------------------- |
|
366 // CLmkIconMap::MinimumSize |
|
367 // |
|
368 // ----------------------------------------------------------------------------- |
|
369 // |
|
370 TSize CLmkIconMap::MinimumSize() |
|
371 { |
|
372 iIsMirrored = AknLayoutUtils::LayoutMirrored(); |
|
373 CountMaxColumnsAndCellSizes(); |
|
374 |
|
375 TRect rect; |
|
376 // Used the set rect, but resolution changes cannot be handled when it is used |
|
377 |
|
378 TAknLayoutRect dialogLayRect; |
|
379 |
|
380 // Main pane without softkeys |
|
381 TRect mainPaneRect; |
|
382 if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, |
|
383 mainPaneRect)) |
|
384 { |
|
385 mainPaneRect = iAvkonAppUi->ClientRect(); |
|
386 } |
|
387 |
|
388 // Dialog layout, check variety first |
|
389 TAknLayoutScalableParameterLimits iconMapDialogVariety = |
|
390 AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits(); |
|
391 |
|
392 // Calc the variety |
|
393 TInt maxVariety = iconMapDialogVariety.LastVariety(); |
|
394 |
|
395 // Check the CBA, if the orientation is not landscape |
|
396 // there is not so much varieties |
|
397 AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation(); |
|
398 TInt maxVarietyOffset = 0; // the offset for the certain cba location variety |
|
399 TInt varietyOffset = maxVariety + 1; // the number of varieties |
|
400 |
|
401 // landscape variety number must be calculated offset == number of varieties |
|
402 // same applies to the variety number for the biggest sized layout for the variety |
|
403 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
404 { |
|
405 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety |
|
406 } |
|
407 |
|
408 // for right and left cba buttons the max variety is not zero |
|
409 // the varities are ordered by the location of the cba and the descending order |
|
410 // e.g the biggest sized layout first, the smallest last |
|
411 if (location == AknLayoutUtils::EAknCbaLocationRight) |
|
412 { |
|
413 maxVarietyOffset = varietyOffset; |
|
414 } |
|
415 else if (location == AknLayoutUtils::EAknCbaLocationLeft) |
|
416 { |
|
417 maxVarietyOffset = varietyOffset + varietyOffset; // 2* |
|
418 } |
|
419 |
|
420 TInt varietyNumber = varietyOffset - iRows - 1; |
|
421 |
|
422 // if more lines than possible to show, use the default |
|
423 // (the biggest grid) variety |
|
424 if (varietyNumber < 0) |
|
425 varietyNumber = 0; |
|
426 // if zero rows, use the minimum |
|
427 else if (iRows <= 0) |
|
428 varietyNumber -= 1; |
|
429 |
|
430 //add the varietyoffset |
|
431 varietyNumber += maxVarietyOffset; |
|
432 |
|
433 if (Layout_Meta_Data::IsLandscapeOrientation() && (location |
|
434 == AknLayoutUtils::EAknCbaLocationRight)) |
|
435 { |
|
436 varietyNumber = 10; |
|
437 } |
|
438 else |
|
439 { |
|
440 if (iRows == 0) |
|
441 { |
|
442 varietyNumber = 5; |
|
443 } |
|
444 else |
|
445 { |
|
446 varietyNumber = 3; |
|
447 } |
|
448 } |
|
449 // Layout the dialog size |
|
450 dialogLayRect.LayoutRect(mainPaneRect, |
|
451 AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber)); |
|
452 |
|
453 // Layout the grid |
|
454 TAknLayoutRect gridWithScrollLayRect; |
|
455 gridWithScrollLayRect.LayoutRect(dialogLayRect.Rect(), |
|
456 AknLayoutScalable_Avkon::listscroll_popup_graphic_pane()); |
|
457 |
|
458 return TSize(dialogLayRect.Rect().Width(), |
|
459 gridWithScrollLayRect.Rect().Height()); |
|
460 } |
|
461 |
|
462 // ----------------------------------------------------------------------------- |
|
463 // CLmkIconMap::ActivateL() |
|
464 // This method is needed to set correct initial value to scroll indicator. |
|
465 // ----------------------------------------------------------------------------- |
|
466 // |
|
467 void CLmkIconMap::ActivateL() |
|
468 { |
|
469 CCoeControl::ActivateL(); |
|
470 if (iRows > Extension()->iMaxVisibleRows) |
|
471 { |
|
472 UpdateScrollIndicatorL(); |
|
473 } |
|
474 } |
|
475 |
|
476 // ----------------------------------------------------------------------------- |
|
477 // CLmkIconMap::OfferKeyEventL |
|
478 // Handles all the Keypad events |
|
479 // ----------------------------------------------------------------------------- |
|
480 // |
|
481 TKeyResponse CLmkIconMap::OfferKeyEventL(const TKeyEvent& aKeyEvent, |
|
482 TEventCode /*aModifiers*/) |
|
483 { |
|
484 TUint code = aKeyEvent.iCode; |
|
485 |
|
486 switch (code) |
|
487 { |
|
488 case EKeyLeftArrow: |
|
489 case '4': |
|
490 MoveCursorL(-1, 0); |
|
491 break; |
|
492 case EKeyRightArrow: |
|
493 case '6': |
|
494 MoveCursorL(1, 0); |
|
495 break; |
|
496 case EKeyUpArrow: |
|
497 case '2': |
|
498 MoveCursorL(0, -1); |
|
499 break; |
|
500 case EKeyDownArrow: |
|
501 case '8': |
|
502 MoveCursorL(0, 1); |
|
503 break; |
|
504 case EKeyOK: |
|
505 case '5': |
|
506 case EKeySpace: |
|
507 case EKeyEnter: |
|
508 { |
|
509 if (iConsArray) |
|
510 { |
|
511 TInt ret = iMaxColumns * (iFirstVisibleRow + iCursorPos.iY) |
|
512 + iCursorPos.iX; |
|
513 if (ret <= iConsArray->Count()) |
|
514 { |
|
515 *iIconIndex = ret; |
|
516 } |
|
517 else |
|
518 { |
|
519 *iIconIndex = -1; |
|
520 } |
|
521 } |
|
522 |
|
523 } |
|
524 break; |
|
525 default: |
|
526 return EKeyWasNotConsumed; |
|
527 |
|
528 } |
|
529 return EKeyWasConsumed; |
|
530 } |
|
531 |
|
532 // ----------------------------------------------------------------------------- |
|
533 // CLmkIconMap::InputCapabilities() |
|
534 // |
|
535 // ----------------------------------------------------------------------------- |
|
536 // |
|
537 TCoeInputCapabilities CLmkIconMap::InputCapabilities() const |
|
538 { |
|
539 return TCoeInputCapabilities(TCoeInputCapabilities::EAllText); |
|
540 } |
|
541 |
|
542 // ----------------------------------------------------------------------------- |
|
543 // CLmkIconMap::SizeChanged() |
|
544 // Control position of this control is registered for skin library when necessary |
|
545 // in CEikDialogPage::SetDataPosition, so we do not do that in this method. |
|
546 // ----------------------------------------------------------------------------- |
|
547 // |
|
548 void CLmkIconMap::SizeChanged() |
|
549 { |
|
550 // Get the layout |
|
551 |
|
552 // Main pane without softkeys |
|
553 TRect mainPaneRect; |
|
554 |
|
555 if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, |
|
556 mainPaneRect)) |
|
557 { |
|
558 mainPaneRect = iAvkonAppUi->ClientRect(); |
|
559 } |
|
560 |
|
561 // Dialog layout, check variety first |
|
562 TAknLayoutScalableParameterLimits iconMapDialogVariety = |
|
563 AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits(); |
|
564 |
|
565 TInt maxVariety = iconMapDialogVariety.LastVariety(); |
|
566 |
|
567 // Check the CBA, if the orientation is not landscape |
|
568 // there is not so much varieties |
|
569 AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation(); |
|
570 TInt maxVarietyOffset = 0; // the offset for the certain cba location variety |
|
571 TInt varietyOffset = maxVariety + 1; |
|
572 |
|
573 // landscape variety number must be calculated offset == number of varieties |
|
574 // same applies to the variety number for the biggest sized layout for the variety |
|
575 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
576 { |
|
577 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety |
|
578 } |
|
579 |
|
580 // for right and left cba buttons the max variety is not zero |
|
581 // the varities are ordered by the location of the cba and the descending order |
|
582 // e.g the biggest sized layout first, the smallest last |
|
583 if (location == AknLayoutUtils::EAknCbaLocationRight) |
|
584 { |
|
585 maxVarietyOffset = varietyOffset; |
|
586 } |
|
587 else if (location == AknLayoutUtils::EAknCbaLocationLeft) |
|
588 { |
|
589 maxVarietyOffset = varietyOffset + varietyOffset; // 2* |
|
590 } |
|
591 |
|
592 TInt varietyNumber = varietyOffset - iRows - 1; |
|
593 |
|
594 // if more lines than possible to show, use the default |
|
595 // (the biggest grid) variety |
|
596 if (varietyNumber < 0) |
|
597 varietyNumber = 0; |
|
598 // if zero rows, use the minimum |
|
599 else if (iRows <= 0) |
|
600 varietyNumber -= 1; |
|
601 |
|
602 //add the varietyoffset |
|
603 varietyNumber += maxVarietyOffset; |
|
604 |
|
605 if (Layout_Meta_Data::IsLandscapeOrientation() && (location |
|
606 == AknLayoutUtils::EAknCbaLocationRight)) |
|
607 { |
|
608 varietyNumber = 10; |
|
609 } |
|
610 else |
|
611 { |
|
612 if (iRows == 0) |
|
613 { |
|
614 varietyNumber = 5; |
|
615 } |
|
616 else |
|
617 { |
|
618 varietyNumber = 3; |
|
619 } |
|
620 |
|
621 } |
|
622 |
|
623 TAknLayoutRect popupGridLayRect; |
|
624 popupGridLayRect.LayoutRect(mainPaneRect, |
|
625 AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber)); |
|
626 |
|
627 // Calculate the size relatively |
|
628 TRect relativeDialog(TPoint(0, 0), popupGridLayRect.Rect().Size()); |
|
629 |
|
630 // Get the layout of the actual icon grid with scrollbar |
|
631 TAknLayoutRect gridWithScrollLayRect; |
|
632 gridWithScrollLayRect.LayoutRect(relativeDialog, |
|
633 AknLayoutScalable_Avkon::listscroll_popup_graphic_pane()); |
|
634 |
|
635 // Then the grid area without scrollbar |
|
636 // NOTE: The grid with scroll bar is used as reference |
|
637 TAknLayoutRect gridLayRect; |
|
638 gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(), |
|
639 AknLayoutScalable_Avkon::grid_graphic_popup_pane(0)); |
|
640 |
|
641 // Different parent if SCT inside editing menu. |
|
642 TRect contentRect = gridLayRect.Rect(); |
|
643 |
|
644 // The x coordinate is 3 pixels to right and y coordinate 3 pixels up |
|
645 // so substract from x coordinate and add to y coordinate |
|
646 if (iIsMirrored) |
|
647 { |
|
648 iOffset = TPoint(contentRect.iBr.iX - KHorizontalDialogMargin |
|
649 - iGridItemWidth + 1, contentRect.iTl.iY |
|
650 - KVerticalDialogMargin + 1); |
|
651 iGridTopLeft.iX = contentRect.iBr.iX - KHorizontalDialogMargin |
|
652 - (iMaxColumns * iGridItemWidth); |
|
653 iGridTopLeft.iY = contentRect.iTl.iY - KVerticalDialogMargin; |
|
654 } |
|
655 else // not mirrored |
|
656 { |
|
657 iOffset = TPoint(contentRect.iTl.iX - KHorizontalDialogMargin + 1, |
|
658 contentRect.iTl.iY - KVerticalDialogMargin + 1); |
|
659 iGridTopLeft.iX = contentRect.iTl.iX - KHorizontalDialogMargin; |
|
660 iGridTopLeft.iY = contentRect.iTl.iY - KVerticalDialogMargin; |
|
661 } |
|
662 |
|
663 // The last, update background context |
|
664 if (Extension()->iBgContext) |
|
665 { |
|
666 TInt bgVariety = 0; |
|
667 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
668 bgVariety = 1; |
|
669 |
|
670 TAknLayoutRect innerRect; |
|
671 innerRect.LayoutRect(relativeDialog, |
|
672 AknLayoutScalable_Avkon::bg_popup_window_pane_g1(bgVariety)); |
|
673 |
|
674 Extension()->iBgContext->SetFrameRects(relativeDialog, |
|
675 innerRect.Rect()); |
|
676 } |
|
677 TRAPD(err, UpdateScrollIndicatorL()); |
|
678 if (err) |
|
679 return; |
|
680 } |
|
681 |
|
682 // ----------------------------------------------------------------------------- |
|
683 // CLmkIconMap::HandleResourceChange() |
|
684 // |
|
685 // ----------------------------------------------------------------------------- |
|
686 // |
|
687 void CLmkIconMap::HandleResourceChange(TInt aType) |
|
688 { |
|
689 if (aType == KEikDynamicLayoutVariantSwitch) |
|
690 { |
|
691 // save the old info for the magnitudes of the SCT grid |
|
692 TInt oldMaxColumns = iMaxColumns; |
|
693 //TInt oldMaxRows = 0; |
|
694 //oldMaxRows = iRows; |
|
695 // calculate the new magnitudes |
|
696 DoLayout(); |
|
697 |
|
698 // then calculate the index position of the cursor in the icon table |
|
699 // and update the x and y positions for the new grid with it |
|
700 |
|
701 TInt oldCursorPosition = (iFirstVisibleRow + iOldCursorPos.iY) |
|
702 * oldMaxColumns + iOldCursorPos.iX; |
|
703 |
|
704 TInt currentCursorPosition = (iFirstVisibleRow + iCursorPos.iY) |
|
705 * oldMaxColumns + iCursorPos.iX; |
|
706 |
|
707 // the new first row is the top row on the page where the new focus is |
|
708 iFirstVisibleRow = Extension()->iMaxVisibleRows |
|
709 * (currentCursorPosition / (iMaxColumns |
|
710 * Extension()->iMaxVisibleRows)); |
|
711 |
|
712 // the cursor positions are relative to current page |
|
713 iCursorPos.iY = (currentCursorPosition - (iMaxColumns |
|
714 * iFirstVisibleRow)) / iMaxColumns; |
|
715 iCursorPos.iX = currentCursorPosition - (iMaxColumns |
|
716 * iFirstVisibleRow) - (iMaxColumns * iCursorPos.iY); |
|
717 |
|
718 iOldCursorPos.iY = (oldCursorPosition - (iMaxColumns |
|
719 * iFirstVisibleRow)) / iMaxColumns; |
|
720 iOldCursorPos.iX = oldCursorPosition - (iMaxColumns |
|
721 * iFirstVisibleRow) - (iMaxColumns * iOldCursorPos.iY); |
|
722 } |
|
723 |
|
724 if (aType == KAknsMessageSkinChange) |
|
725 { |
|
726 iOffscreenBgDrawn = EFalse; |
|
727 } |
|
728 CCoeControl::HandleResourceChange(aType); |
|
729 |
|
730 } |
|
731 |
|
732 // ----------------------------------------------------------------------------- |
|
733 // CLmkIconMap::Draw() |
|
734 // |
|
735 // ----------------------------------------------------------------------------- |
|
736 // |
|
737 void CLmkIconMap::Draw(const TRect& /*aRect*/) const |
|
738 { |
|
739 |
|
740 TInt cursorPos = 0; |
|
741 CWindowGc& gc = SystemGc(); |
|
742 |
|
743 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
744 MAknsControlContext* cc = AknsDrawUtils::ControlContext(this); |
|
745 |
|
746 TRect rect = Rect(); |
|
747 |
|
748 // Main pane without softkeys |
|
749 TRect mainPaneRect; |
|
750 if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, |
|
751 mainPaneRect)) |
|
752 { |
|
753 mainPaneRect = iAvkonAppUi->ClientRect(); |
|
754 } |
|
755 |
|
756 // Dialog layout, check variety first |
|
757 TAknLayoutScalableParameterLimits iconMapDialogVariety = |
|
758 AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits(); |
|
759 |
|
760 // The variety starts from 0 so add +1 |
|
761 TInt maxVariety = iconMapDialogVariety.LastVariety(); |
|
762 |
|
763 // Check the CBA, if the orientation is not landscape |
|
764 // there is not so much varieties |
|
765 AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation(); |
|
766 TInt maxVarietyOffset = 0; // the offset for the certain cba location variety |
|
767 TInt varietyOffset = maxVariety + 1; |
|
768 |
|
769 // landscape variety number must be calculated offset == number of varieties |
|
770 // same applies to the variety number for the biggest sized layout for the variety |
|
771 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
772 { |
|
773 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety |
|
774 } |
|
775 |
|
776 // for right and left cba buttons the max variety is not zero |
|
777 // the varities are ordered by the location of the cba and the descending order |
|
778 // e.g the biggest sized layout first, the smallest last |
|
779 if (location == AknLayoutUtils::EAknCbaLocationRight) |
|
780 { |
|
781 maxVarietyOffset = varietyOffset; |
|
782 } |
|
783 else if (location == AknLayoutUtils::EAknCbaLocationLeft) |
|
784 { |
|
785 maxVarietyOffset = varietyOffset + varietyOffset; // 2* |
|
786 } |
|
787 |
|
788 TInt varietyNumber = varietyOffset - iRows - 1; |
|
789 |
|
790 // if more lines than possible to show, use the default |
|
791 // (the biggest grid) variety |
|
792 if (varietyNumber < 0) |
|
793 varietyNumber = 0; |
|
794 // if zero rows, use the minimum |
|
795 else if (iRows <= 0) |
|
796 varietyNumber -= 1; |
|
797 |
|
798 //add the varietyoffset |
|
799 varietyNumber += maxVarietyOffset; |
|
800 |
|
801 if (Layout_Meta_Data::IsLandscapeOrientation() && (location |
|
802 == AknLayoutUtils::EAknCbaLocationRight)) |
|
803 { |
|
804 varietyNumber = 10; |
|
805 } |
|
806 else |
|
807 { |
|
808 varietyNumber = 3; |
|
809 } |
|
810 // Layout the dialog size |
|
811 TAknLayoutRect dialogLayRect; |
|
812 dialogLayRect.LayoutRect(mainPaneRect, |
|
813 AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber)); |
|
814 |
|
815 // Get the missing height for the background |
|
816 TInt backgroundHeightOffset = dialogLayRect.Rect().Height() - rect.iBr.iY; |
|
817 |
|
818 rect.iBr.iY += backgroundHeightOffset; |
|
819 |
|
820 // Check if we got an offscreen bitmap allocated for skin background and |
|
821 // there is bitmap background in the current skin. |
|
822 if (iOffscreenBg && iHasBitmapBackground) |
|
823 { |
|
824 DrawOffscreenBackgroundIfRequired(); |
|
825 gc.BitBlt(rect.iTl, iOffscreenBg); |
|
826 } |
|
827 else |
|
828 { |
|
829 AknsDrawUtils::Background(skin, cc, this, gc, rect); |
|
830 } |
|
831 |
|
832 TInt numberOfIconsToBeDrawn = iConsArray->Count(); |
|
833 numberOfIconsToBeDrawn -= (iFirstVisibleRow * iMaxColumns); |
|
834 if (numberOfIconsToBeDrawn > 0) |
|
835 { |
|
836 if (numberOfIconsToBeDrawn > (Extension()->iMaxVisibleRows |
|
837 * iMaxColumns)) |
|
838 { |
|
839 numberOfIconsToBeDrawn = Extension()->iMaxVisibleRows |
|
840 * iMaxColumns; |
|
841 } |
|
842 __ASSERT_DEBUG( numberOfIconsToBeDrawn >= 1, Panic( KLmkPanicOutOfRange ) ); |
|
843 |
|
844 gc.SetPenStyle(CGraphicsContext::ESolidPen); |
|
845 gc.SetBrushStyle(CGraphicsContext::ENullBrush); |
|
846 gc.SetPenSize(TSize(1, 1)); |
|
847 |
|
848 // 2) Draw the grid |
|
849 const TSize gridItemRectSize(iGridItemWidth + 1, iGridItemHeight + 1); |
|
850 |
|
851 TInt numberOfGridCellsToBeDrawn = numberOfIconsToBeDrawn; |
|
852 |
|
853 TRgb colorLine = AKN_LAF_COLOR(219); |
|
854 AknsUtils::GetCachedColor(skin, colorLine, KAknsIIDQsnLineColors, |
|
855 EAknsCIQsnLineColorsCG5); |
|
856 TRgb colorRecentLine = AKN_LAF_COLOR(215); |
|
857 AknsUtils::GetCachedColor(skin, colorRecentLine, |
|
858 KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7); |
|
859 |
|
860 // default pen color |
|
861 gc.SetPenColor(colorLine); |
|
862 |
|
863 TInt fullRows = numberOfGridCellsToBeDrawn / iMaxColumns; |
|
864 |
|
865 // how many left after the full rows |
|
866 numberOfGridCellsToBeDrawn -= fullRows * iMaxColumns; |
|
867 |
|
868 TPoint pos = iGridTopLeft; |
|
869 |
|
870 TInt endX = pos.iX + iGridItemWidth * iMaxColumns + 1; |
|
871 TInt endY = pos.iY + iGridItemHeight * fullRows; |
|
872 |
|
873 TInt ii = 0; |
|
874 |
|
875 if (fullRows) |
|
876 { |
|
877 // Draw full vertical lines |
|
878 for (ii = 0; ii <= iMaxColumns; ii++) |
|
879 { |
|
880 gc.SetPenColor(colorLine); |
|
881 gc.SetPenSize(TSize(1, 1)); |
|
882 gc.DrawLine(pos, TPoint(pos.iX, endY)); |
|
883 pos.iX += iGridItemWidth; |
|
884 } |
|
885 |
|
886 pos = iGridTopLeft; |
|
887 |
|
888 // Draw full horizontal lines |
|
889 for (ii = 0; ii <= fullRows; ii++) |
|
890 { |
|
891 gc.SetPenSize(TSize(1, 1)); |
|
892 gc.SetPenColor(colorLine); |
|
893 gc.DrawLine(pos, TPoint(endX, pos.iY)); |
|
894 pos.iY += iGridItemHeight; |
|
895 } |
|
896 gc.SetPenColor(colorLine); |
|
897 gc.SetPenSize(TSize(1, 1)); |
|
898 } |
|
899 |
|
900 if (numberOfGridCellsToBeDrawn) |
|
901 { |
|
902 // Remaining cells in the last, non-full row |
|
903 pos = iOffset; |
|
904 pos.iX--; // iOffset is cell area topLeft, grid is not included in it |
|
905 pos.iY--; |
|
906 |
|
907 pos.iY += iGridItemHeight * fullRows; |
|
908 |
|
909 for (ii = 0; ii < numberOfGridCellsToBeDrawn; ii++) |
|
910 { |
|
911 gc.DrawRect(TRect(pos, gridItemRectSize)); |
|
912 |
|
913 if (iIsMirrored) |
|
914 pos.iX -= iGridItemWidth; |
|
915 else |
|
916 // not mirrored |
|
917 pos.iX += iGridItemWidth; |
|
918 } |
|
919 } |
|
920 |
|
921 TInt iconIndex = (iCurrentPage - 1) * (iMaxColumns |
|
922 * Extension()->iMaxVisibleRows); |
|
923 TInt lCnt = iConsArray->Count(); |
|
924 cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns; |
|
925 if (lCnt > 0) |
|
926 { |
|
927 TRect cellRect(TPoint(0, 0), TSize(iGridItemWidth - 1, |
|
928 iGridItemHeight - 1)); |
|
929 for (TInt j = iconIndex, i = 0; j < lCnt && (i |
|
930 < numberOfIconsToBeDrawn); j++, i++) |
|
931 { |
|
932 DrawItem(gc, CursorRect(i), j, (cursorPos == i), EFalse); |
|
933 } |
|
934 } |
|
935 |
|
936 } |
|
937 iDrawnBefore = ETrue; |
|
938 gc.DiscardFont(); |
|
939 } |
|
940 |
|
941 // ----------------------------------------------------------------------------- |
|
942 // CLmkIconMap::DrawItem() |
|
943 // |
|
944 // ----------------------------------------------------------------------------- |
|
945 // |
|
946 void CLmkIconMap::DrawItem(CWindowGc& aGc, const TRect& aSctPosition, |
|
947 TInt aIconIndex, TBool aHighlighted, TBool aDrawBackground) const |
|
948 { |
|
949 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
950 MAknsControlContext* cc = AknsDrawUtils::ControlContext(this); |
|
951 |
|
952 TBool skins = AknsDrawUtils::Background(skin, cc, aGc, aSctPosition); |
|
953 TRgb color; |
|
954 if (!skins) |
|
955 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
956 if (aHighlighted) |
|
957 { |
|
958 TRgb colorHightLightRect = AKN_LAF_COLOR(215); |
|
959 AknsUtils::GetCachedColor(skin, colorHightLightRect, |
|
960 KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7); |
|
961 aGc.SetPenColor(colorHightLightRect); |
|
962 aGc.DrawRect(aSctPosition); |
|
963 |
|
964 // Shrink by one pixel in all directions. |
|
965 TRect innerRect = aSctPosition; |
|
966 innerRect.Shrink(1, 1); |
|
967 |
|
968 color = AKN_LAF_COLOR(210); |
|
969 AknsUtils::GetCachedColor(skin, color, KAknsIIDQsnHighlightColors, |
|
970 EAknsCIQsnHighlightColorsCG1); |
|
971 aGc.SetBrushColor(color); |
|
972 aGc.Clear(innerRect); |
|
973 } |
|
974 else if (aDrawBackground) |
|
975 { |
|
976 TRect innerRect = aSctPosition; |
|
977 aGc.SetBrushColor(AKN_LAF_COLOR(0)); |
|
978 if (!skins) |
|
979 aGc.Clear(innerRect); |
|
980 else |
|
981 AknsDrawUtils::Background(skin, cc, this, aGc, innerRect); |
|
982 } |
|
983 |
|
984 if (iConsArray) |
|
985 { |
|
986 TInt lCnt = iConsArray->Count(); |
|
987 if (lCnt > 0 && aIconIndex < lCnt && aIconIndex >= 0) |
|
988 { |
|
989 TRect cellRect(TPoint(0, 0), TSize(iGridItemWidth - 1, |
|
990 iGridItemHeight - 1)); |
|
991 |
|
992 CGulIcon* bitmap = NULL; |
|
993 bitmap = iConsArray->At(aIconIndex); |
|
994 TInt numIconsInaPage = Extension()->iMaxVisibleRows * iMaxColumns; |
|
995 TInt cellIndex = aIconIndex; |
|
996 if (aIconIndex >= numIconsInaPage) |
|
997 { |
|
998 cellIndex = aIconIndex % numIconsInaPage; |
|
999 } |
|
1000 aGc.BitBltMasked(CursorPoint(cellIndex), bitmap->Bitmap(), |
|
1001 cellRect, bitmap->Mask(), EFalse); |
|
1002 } |
|
1003 } |
|
1004 } |
|
1005 |
|
1006 // ----------------------------------------------------------------------------- |
|
1007 // CLmkIconMap::DrawCursor() |
|
1008 // Optimizes drawing. Only cursor is drawn. |
|
1009 // ----------------------------------------------------------------------------- |
|
1010 void CLmkIconMap::DrawCursor() const |
|
1011 { |
|
1012 // Whole Icon Map has to be drawn at least once. |
|
1013 // If the user presses arrow key before Icon Map has been drawn, |
|
1014 // only cursor position is drawn without this check. |
|
1015 if (!iDrawnBefore) |
|
1016 { |
|
1017 DrawNow(); |
|
1018 } |
|
1019 // Only redraw old and new cursor position cells |
|
1020 ActivateGc(); |
|
1021 CWindowGc& gc = SystemGc(); |
|
1022 |
|
1023 TInt cursorPos = iOldCursorPos.iX + iOldCursorPos.iY * iMaxColumns; |
|
1024 if (cursorPos >= 0) |
|
1025 { |
|
1026 DrawCell(cursorPos, EFalse); |
|
1027 |
|
1028 cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns; |
|
1029 DrawCell(cursorPos, ETrue); |
|
1030 } |
|
1031 |
|
1032 gc.DiscardFont(); |
|
1033 DeactivateGc(); |
|
1034 } |
|
1035 |
|
1036 // ----------------------------------------------------------------------------- |
|
1037 // CLmkIconMap::DrawCell |
|
1038 // ----------------------------------------------------------------------------- |
|
1039 // |
|
1040 void CLmkIconMap::DrawCell(TInt aCursorPos, TBool aHighLighted) const |
|
1041 { |
|
1042 // calculate icon index |
|
1043 TInt iconIndex = aCursorPos + iFirstVisibleRow * iMaxColumns; |
|
1044 |
|
1045 // If we are only redrawing for animations, no need to draw non-animated items. |
|
1046 TRect rect = CursorRect(aCursorPos); |
|
1047 |
|
1048 Window().Invalidate(rect); |
|
1049 Window().BeginRedraw(rect); |
|
1050 DrawItem(SystemGc(), rect, iconIndex, aHighLighted, ETrue); |
|
1051 Window().EndRedraw(); |
|
1052 SystemGc().DiscardFont(); |
|
1053 } |
|
1054 |
|
1055 // ----------------------------------------------------------------------------- |
|
1056 // CLmkIconMap::CursorRect |
|
1057 // ----------------------------------------------------------------------------- |
|
1058 // |
|
1059 TRect CLmkIconMap::CursorRect(TInt aCursorPos) const |
|
1060 { |
|
1061 TPoint pos = iOffset; |
|
1062 |
|
1063 if (iIsMirrored) |
|
1064 { |
|
1065 pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth; |
|
1066 } |
|
1067 else // Not mirrored |
|
1068 { |
|
1069 pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth; |
|
1070 } |
|
1071 |
|
1072 pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight; |
|
1073 return TRect(pos, TSize(iGridItemWidth - 1, iGridItemHeight - 1)); |
|
1074 } |
|
1075 |
|
1076 // ----------------------------------------------------------------------------- |
|
1077 // CLmkIconMap::CursorPoint |
|
1078 // ----------------------------------------------------------------------------- |
|
1079 // |
|
1080 TPoint CLmkIconMap::CursorPoint(TInt aCursorPos) const |
|
1081 { |
|
1082 TPoint pos = iOffset; |
|
1083 |
|
1084 if (iIsMirrored) |
|
1085 { |
|
1086 pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth; |
|
1087 } |
|
1088 else // Not mirrored |
|
1089 { |
|
1090 pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth; |
|
1091 } |
|
1092 |
|
1093 pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight; |
|
1094 return pos; |
|
1095 } |
|
1096 |
|
1097 // ----------------------------------------------------------------------------- |
|
1098 // CLmkIconMap::MoveCursorL |
|
1099 // ----------------------------------------------------------------------------- |
|
1100 // |
|
1101 void CLmkIconMap::MoveCursorL(TInt aDeltaX, TInt aDeltaY) |
|
1102 { |
|
1103 __ASSERT_DEBUG((aDeltaX <= 1) && (aDeltaX >= -1) && (aDeltaY <= 1) |
|
1104 && (aDeltaY >= -1) && ((aDeltaX * aDeltaY) == 0), Panic( |
|
1105 KLmkPanicOutOfRange)); |
|
1106 |
|
1107 if (iIsMirrored) |
|
1108 aDeltaX = -aDeltaX; |
|
1109 |
|
1110 if ((iConsArray->Count() < 8)) |
|
1111 return; |
|
1112 |
|
1113 iOldCursorPos = iCursorPos; |
|
1114 TInt oldFirstVisibleRow = iFirstVisibleRow; |
|
1115 |
|
1116 TInt globalYPos = iCursorPos.iY + iFirstVisibleRow; |
|
1117 TInt lastColumnOnLastRow = ((iConsArray->Count() - 1) % iMaxColumns); |
|
1118 |
|
1119 TInt skipicon = aDeltaX != 0 ? 1 : 0; |
|
1120 |
|
1121 if (aDeltaX < 0) |
|
1122 { |
|
1123 // Cursor was moved to left. |
|
1124 if (iCursorPos.iX > skipicon - 1) |
|
1125 { |
|
1126 iCursorPos.iX -= skipicon; |
|
1127 } |
|
1128 else |
|
1129 { |
|
1130 if (skipicon > iMaxColumns) |
|
1131 { |
|
1132 globalYPos--; |
|
1133 iCursorPos.iX = iMaxColumns; |
|
1134 } |
|
1135 // Go to previous line |
|
1136 globalYPos--; |
|
1137 if (globalYPos < 0) |
|
1138 { |
|
1139 // Cursor was on the first line - go to last line. |
|
1140 globalYPos = iRows - 1; |
|
1141 // x - position to the last item on the last row. |
|
1142 iCursorPos.iX = lastColumnOnLastRow; |
|
1143 } |
|
1144 else |
|
1145 { |
|
1146 // x - position to last column. |
|
1147 iCursorPos.iX = iMaxColumns - skipicon; |
|
1148 } |
|
1149 } |
|
1150 } |
|
1151 |
|
1152 if (aDeltaX > 0) |
|
1153 { |
|
1154 // Cursor was moved to right. |
|
1155 if (globalYPos < iRows - 1) |
|
1156 { |
|
1157 // Not in the last row. |
|
1158 if (iCursorPos.iX < iMaxColumns - skipicon) |
|
1159 { |
|
1160 // If not on the last columns, move cursor to next column. |
|
1161 iCursorPos.iX += skipicon; |
|
1162 } |
|
1163 else |
|
1164 { |
|
1165 // Cursor was on last column, |
|
1166 // move to first column of the next line. |
|
1167 iCursorPos.iX = 0; |
|
1168 globalYPos++; |
|
1169 } |
|
1170 } |
|
1171 else |
|
1172 { |
|
1173 // Currently on the last row. |
|
1174 if (iCursorPos.iX < lastColumnOnLastRow) |
|
1175 { |
|
1176 // If there are more items on this row, move cursor to next item. |
|
1177 iCursorPos.iX++; |
|
1178 } |
|
1179 else |
|
1180 { |
|
1181 // No more item on the current row. |
|
1182 // Move to first item on the first row. |
|
1183 iCursorPos.iX = 0; |
|
1184 globalYPos = 0; |
|
1185 } |
|
1186 } |
|
1187 } |
|
1188 |
|
1189 if (aDeltaY < 0) |
|
1190 { |
|
1191 iCursorPos.iX -= skipicon; |
|
1192 if (iCursorPos.iX < 0) |
|
1193 { |
|
1194 iCursorPos.iX += (iMaxColumns - 1); |
|
1195 globalYPos--; |
|
1196 } |
|
1197 // Cursor was moved to up. |
|
1198 if (globalYPos > 0) |
|
1199 { |
|
1200 // Cursor was not on the first line - move it to previous row. |
|
1201 globalYPos--; |
|
1202 } |
|
1203 else |
|
1204 { |
|
1205 // Move cursot to last to row. |
|
1206 globalYPos = iRows - 1; |
|
1207 if (iCursorPos.iX > lastColumnOnLastRow) |
|
1208 { |
|
1209 // No items in the current column on the last row - |
|
1210 // move cursor to last item on the row. |
|
1211 iCursorPos.iX = lastColumnOnLastRow; |
|
1212 } |
|
1213 } |
|
1214 } |
|
1215 |
|
1216 if (aDeltaY > 0) |
|
1217 { |
|
1218 iCursorPos.iX = (iCursorPos.iX + skipicon) % iMaxColumns; |
|
1219 globalYPos += (iCursorPos.iX + skipicon) / iMaxColumns; |
|
1220 // Cursor was moved to down. |
|
1221 if (globalYPos < iRows - 1) |
|
1222 { |
|
1223 // Cursor is not on the last row. Move cursor to next row. |
|
1224 globalYPos++; |
|
1225 if (globalYPos == iRows - 1 && iCursorPos.iX |
|
1226 > lastColumnOnLastRow) |
|
1227 { |
|
1228 // No items in the current column on the last row - |
|
1229 // move cursor to last item on the row. |
|
1230 iCursorPos.iX = lastColumnOnLastRow; |
|
1231 } |
|
1232 } |
|
1233 else |
|
1234 { |
|
1235 // Cursor was at the last row - move it to the first row. |
|
1236 globalYPos = 0; |
|
1237 } |
|
1238 } |
|
1239 iCursorPos.iY = globalYPos - iFirstVisibleRow; |
|
1240 |
|
1241 if (globalYPos < iFirstVisibleRow) |
|
1242 { |
|
1243 // Cursor was moved from the top row. |
|
1244 if (globalYPos <= 0) |
|
1245 { |
|
1246 iFirstVisibleRow = 0; |
|
1247 iCursorPos = TPoint(iCursorPos.iX, 0); |
|
1248 } |
|
1249 else |
|
1250 { |
|
1251 // If cursor was moved up out of the visible area - show it again. |
|
1252 iFirstVisibleRow -= Extension()->iMaxVisibleRows; |
|
1253 iCursorPos = TPoint(iCursorPos.iX, Extension()->iMaxVisibleRows |
|
1254 - 1); |
|
1255 } |
|
1256 } |
|
1257 |
|
1258 if (globalYPos > iFirstVisibleRow + Extension()->iMaxVisibleRows - 1) |
|
1259 { |
|
1260 if (globalYPos == iRows - 1) |
|
1261 { |
|
1262 // When cursor has moved from the top line, |
|
1263 // it is adjusted to a page boundary. |
|
1264 iCursorPos = TPoint(iCursorPos.iX, (iRows - 1) |
|
1265 % Extension()->iMaxVisibleRows); |
|
1266 iFirstVisibleRow = ((iRows - 1) / Extension()->iMaxVisibleRows) |
|
1267 * Extension()->iMaxVisibleRows; |
|
1268 } |
|
1269 else |
|
1270 { |
|
1271 // If cursor was moved down out of the visible area - show it again. |
|
1272 iFirstVisibleRow += Extension()->iMaxVisibleRows; |
|
1273 iCursorPos = TPoint(iCursorPos.iX, 0); |
|
1274 } |
|
1275 } |
|
1276 |
|
1277 //TInt increment(1); |
|
1278 //if (aDeltaY < 0 || aDeltaX < 0) |
|
1279 // { |
|
1280 //// increment = -1; |
|
1281 // } |
|
1282 if ((iRows > Extension()->iMaxVisibleRows) && (iOldCursorPos.iY |
|
1283 + oldFirstVisibleRow != iCursorPos.iY + iFirstVisibleRow)) |
|
1284 { |
|
1285 UpdateScrollIndicatorL(); |
|
1286 } |
|
1287 |
|
1288 if (oldFirstVisibleRow == iFirstVisibleRow) |
|
1289 { |
|
1290 // Draw only cursor if the view to the content was not scrolled. |
|
1291 DrawCursor(); |
|
1292 } |
|
1293 else |
|
1294 { |
|
1295 DrawNow(); |
|
1296 } |
|
1297 |
|
1298 } |
|
1299 |
|
1300 // ----------------------------------------------------------------------------- |
|
1301 // CLmkIconMap::UpdateScrollIndicatorL() |
|
1302 // |
|
1303 // ----------------------------------------------------------------------------- |
|
1304 // |
|
1305 void CLmkIconMap::UpdateScrollIndicatorL() |
|
1306 { |
|
1307 if (!iSBFrame) |
|
1308 { |
|
1309 return; |
|
1310 } |
|
1311 TEikScrollBarModel hSbarModel; |
|
1312 TEikScrollBarModel vSbarModel; |
|
1313 |
|
1314 TEikScrollBarFrameLayout layout; |
|
1315 |
|
1316 // Main pane without softkeys |
|
1317 TRect mainPaneRect; |
|
1318 if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, |
|
1319 mainPaneRect)) |
|
1320 { |
|
1321 mainPaneRect = iAvkonAppUi->ClientRect(); |
|
1322 } |
|
1323 |
|
1324 // Dialog layout, check variety first |
|
1325 TAknLayoutScalableParameterLimits iconMapDialogVariety = |
|
1326 AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits(); |
|
1327 |
|
1328 TInt maxVariety = iconMapDialogVariety.LastVariety(); |
|
1329 |
|
1330 // Check the CBA, if the orientation is not landscape |
|
1331 // there is not so much varieties |
|
1332 AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation(); |
|
1333 TInt maxVarietyOffset = 0; // the offset for the certain cba location variety |
|
1334 TInt varietyOffset = maxVariety + 1; |
|
1335 |
|
1336 // landscape variety number must be calculated offset == number of varieties |
|
1337 // same applies to the variety number for the biggest sized layout for the variety |
|
1338 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
1339 { |
|
1340 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety |
|
1341 } |
|
1342 |
|
1343 // for right and left cba buttons the max variety is not zero |
|
1344 // the varities are ordered by the location of the cba and the descending order |
|
1345 // e.g the biggest sized layout first, the smallest last |
|
1346 if (location == AknLayoutUtils::EAknCbaLocationRight) |
|
1347 { |
|
1348 maxVarietyOffset = varietyOffset; |
|
1349 } |
|
1350 else if (location == AknLayoutUtils::EAknCbaLocationLeft) |
|
1351 { |
|
1352 maxVarietyOffset = varietyOffset + varietyOffset; // 2* |
|
1353 } |
|
1354 |
|
1355 TInt varietyNumber = varietyOffset - iRows - 1; |
|
1356 |
|
1357 // if more lines than possible to show, use the default |
|
1358 // (the biggest grid) variety |
|
1359 if (varietyNumber < 0) |
|
1360 varietyNumber = 0; |
|
1361 // if zero rows, use the minimum |
|
1362 else if (iRows <= 0) |
|
1363 varietyNumber -= 1; |
|
1364 |
|
1365 //add the varietyoffset |
|
1366 varietyNumber += maxVarietyOffset; |
|
1367 |
|
1368 if (Layout_Meta_Data::IsLandscapeOrientation() && (location |
|
1369 == AknLayoutUtils::EAknCbaLocationRight)) |
|
1370 { |
|
1371 varietyNumber = 10; |
|
1372 } |
|
1373 else |
|
1374 { |
|
1375 varietyNumber = 3; |
|
1376 } |
|
1377 // Layout the dialog size |
|
1378 TAknLayoutRect dialogLayRect; |
|
1379 dialogLayRect.LayoutRect(mainPaneRect, |
|
1380 AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber)); |
|
1381 |
|
1382 TRect dialogRect = dialogLayRect.Rect(); |
|
1383 |
|
1384 // Get the layout of the actual icon grid with scrollbar |
|
1385 TAknLayoutRect gridWithScrollLayRect; |
|
1386 |
|
1387 gridWithScrollLayRect.LayoutRect(TRect(TPoint(0, 0), TSize( |
|
1388 dialogRect.Size())), |
|
1389 AknLayoutScalable_Avkon::listscroll_popup_graphic_pane()); |
|
1390 |
|
1391 // Calculate the relative rect for the grid |
|
1392 TRect parent = gridWithScrollLayRect.Rect(); |
|
1393 |
|
1394 TAknWindowComponentLayout scrollbarLayout = |
|
1395 AknLayoutScalable_Avkon::scroll_pane_cp5(); |
|
1396 |
|
1397 iCurrentPage = (iFirstVisibleRow / Extension()->iMaxVisibleRows) + 1; |
|
1398 |
|
1399 vSbarModel.iScrollSpan = iNumPages * Extension()->iMaxVisibleRows; |
|
1400 vSbarModel.iThumbSpan = Extension()->iMaxVisibleRows; |
|
1401 |
|
1402 if (iSBFrame && iSBFrame->TypeOfVScrollBar() |
|
1403 == CEikScrollBarFrame::EDoubleSpan) |
|
1404 { |
|
1405 // For EDoubleSpan type scrollbar |
|
1406 vSbarModel.iThumbPosition = (iCurrentPage - 1) |
|
1407 * Extension()->iMaxVisibleRows; |
|
1408 TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel); |
|
1409 TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel); |
|
1410 |
|
1411 // The y coordinate must be sifted 3 pixels up and x 3 to left |
|
1412 parent.iTl.iY -= KVerticalDialogMargin; |
|
1413 parent.iBr.iY -= KVerticalDialogMargin; |
|
1414 parent.iTl.iX -= KHorizontalDialogMargin; |
|
1415 parent.iBr.iX -= KHorizontalDialogMargin; |
|
1416 |
|
1417 layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant; |
|
1418 iSBFrame->Tile(&vDsSbarModel); |
|
1419 AknLayoutUtils::LayoutVerticalScrollBar(iSBFrame, parent, |
|
1420 scrollbarLayout); |
|
1421 iSBFrame->SetVFocusPosToThumbPos(vDsSbarModel.FocusPosition()); |
|
1422 } |
|
1423 else |
|
1424 { |
|
1425 // For EArrowHead type scrollbar |
|
1426 vSbarModel.iThumbPosition = iCursorPos.iY + iFirstVisibleRow; |
|
1427 iSBFrame->TileL(&hSbarModel, &vSbarModel, parent, parent, layout); |
|
1428 iSBFrame->SetVFocusPosToThumbPos(vSbarModel.iThumbPosition); |
|
1429 } |
|
1430 } |
|
1431 |
|
1432 // ----------------------------------------------------------------------------- |
|
1433 // CLmkIconMap::Reserved_1() |
|
1434 // |
|
1435 // ----------------------------------------------------------------------------- |
|
1436 // |
|
1437 void CLmkIconMap::Reserved_1() |
|
1438 { |
|
1439 } |
|
1440 |
|
1441 // ----------------------------------------------------------------------------- |
|
1442 // CLmkIconMap::Reserved_2() |
|
1443 // |
|
1444 // ----------------------------------------------------------------------------- |
|
1445 // |
|
1446 void CLmkIconMap::Reserved_2() |
|
1447 { |
|
1448 } |
|
1449 |
|
1450 // ----------------------------------------------------------------------------- |
|
1451 // CLmkIconMap::DrawOffscreenBackgroundIfRequired |
|
1452 // |
|
1453 // ----------------------------------------------------------------------------- |
|
1454 // |
|
1455 void CLmkIconMap::DrawOffscreenBackgroundIfRequired() const |
|
1456 { |
|
1457 if (iOffscreenBg && iHasBitmapBackground) |
|
1458 { |
|
1459 if (!iOffscreenBgDrawn) |
|
1460 { |
|
1461 TRect mainPaneRect; |
|
1462 if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, |
|
1463 mainPaneRect)) |
|
1464 { |
|
1465 mainPaneRect = iAvkonAppUi->ClientRect(); |
|
1466 } |
|
1467 |
|
1468 // Dialog layout, check variety first |
|
1469 TAknLayoutScalableParameterLimits |
|
1470 iconMapDialogVariety = |
|
1471 AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits(); |
|
1472 |
|
1473 TInt maxVariety = iconMapDialogVariety.LastVariety(); |
|
1474 |
|
1475 // Check the CBA, if the orientation is not landscape |
|
1476 // there is not so much varieties |
|
1477 AknLayoutUtils::TAknCbaLocation location = |
|
1478 AknLayoutUtils::CbaLocation(); |
|
1479 TInt maxVarietyOffset = 0; // the offset for the certain cba location variety |
|
1480 TInt varietyOffset = maxVariety + 1; |
|
1481 |
|
1482 // landscape variety number must be calculated offset == number of varieties |
|
1483 // same applies to the variety number for the biggest sized layout for the variety |
|
1484 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
1485 { |
|
1486 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety |
|
1487 } |
|
1488 |
|
1489 // for right and left cba buttons the max variety is not zero |
|
1490 // the varities are ordered by the location of the cba and the descending order |
|
1491 // e.g the biggest sized layout first, the smallest last |
|
1492 if (location == AknLayoutUtils::EAknCbaLocationRight) |
|
1493 { |
|
1494 maxVarietyOffset = varietyOffset; |
|
1495 } |
|
1496 else if (location == AknLayoutUtils::EAknCbaLocationLeft) |
|
1497 { |
|
1498 maxVarietyOffset = varietyOffset + varietyOffset; // 2* |
|
1499 } |
|
1500 TInt varietyNumber = varietyOffset - iRows - 1; |
|
1501 |
|
1502 // if more lines than possible to show, use the default |
|
1503 // (the biggest grid) variety |
|
1504 if (varietyNumber < 0) |
|
1505 varietyNumber = 0; |
|
1506 // if zero rows, use the minimum |
|
1507 else if (iRows <= 0) |
|
1508 varietyNumber -= 1; |
|
1509 |
|
1510 //add the varietyoffset |
|
1511 varietyNumber += maxVarietyOffset; |
|
1512 |
|
1513 TAknLayoutRect popupGridLayRect; |
|
1514 popupGridLayRect.LayoutRect(mainPaneRect, |
|
1515 AknLayoutScalable_Avkon::popup_grid_graphic_window(5)); |
|
1516 |
|
1517 TRect popupGridRect = popupGridLayRect.Rect(); |
|
1518 |
|
1519 // set the top left height as the control starting point |
|
1520 popupGridRect.iTl.iY = Rect().iTl.iY; |
|
1521 |
|
1522 //if(popupGridRect.iBr.iY < mainPaneRect.iBr.iY) |
|
1523 // popupGridRect.iBr.iY = mainPaneRect.iBr.iY |
|
1524 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
1525 MAknsControlContext* cc = AknsDrawUtils::ControlContext(this); |
|
1526 |
|
1527 // draw to upper left corner, and normalize the retangle to |
|
1528 // fact that the dialog starts from coordinates (0,0), |
|
1529 // so the y-coordinate is correct (heading pane) |
|
1530 // but x must be set to zero |
|
1531 TPoint point = TPoint(0, 0); |
|
1532 popupGridRect.Move(-popupGridRect.iTl.iX, 0); |
|
1533 |
|
1534 AknsDrawUtils::DrawBackground(skin, cc, this, *iBitmapGc, point, |
|
1535 popupGridRect, KAknsDrawParamDefault); |
|
1536 |
|
1537 iOffscreenBgDrawn = ETrue; |
|
1538 } |
|
1539 } |
|
1540 } |
|
1541 |
|
1542 // ----------------------------------------------------------------------------- |
|
1543 // CLmkIconMap::ComponentControl(TInt aIndex) const |
|
1544 // Return the controll pointer |
|
1545 // ----------------------------------------------------------------------------- |
|
1546 // |
|
1547 CCoeControl* CLmkIconMap::ComponentControl(TInt aIndex) const |
|
1548 { |
|
1549 if (aIndex == 0 && iSBFrame && iSBFrame->TypeOfVScrollBar() |
|
1550 == CEikScrollBarFrame::EDoubleSpan) |
|
1551 { |
|
1552 return iSBFrame->VerticalScrollBar(); |
|
1553 } |
|
1554 else |
|
1555 { |
|
1556 return NULL; |
|
1557 } |
|
1558 } |
|
1559 |
|
1560 // ----------------------------------------------------------------------------- |
|
1561 // CLmkIconMap::CountComponentControls() |
|
1562 // Return no of controll to be placed on the container control |
|
1563 // ----------------------------------------------------------------------------- |
|
1564 // |
|
1565 TInt CLmkIconMap::CountComponentControls() const |
|
1566 { |
|
1567 if (iSBFrame && iSBFrame->TypeOfVScrollBar() |
|
1568 == CEikScrollBarFrame::EDoubleSpan) |
|
1569 { |
|
1570 return 1; |
|
1571 } |
|
1572 else |
|
1573 { |
|
1574 return 0; |
|
1575 } |
|
1576 } |
|
1577 |
|
1578 // ----------------------------------------------------------------------------- |
|
1579 // CLmkIconMap::CountMaxColumnsAndCellSizes |
|
1580 // Counts no of columns and the cell size will be displayed in the icon table |
|
1581 // ----------------------------------------------------------------------------- |
|
1582 // |
|
1583 void CLmkIconMap::CountMaxColumnsAndCellSizes() |
|
1584 { |
|
1585 |
|
1586 TRect cellRect; // retangle of one item in grid |
|
1587 TRect gridRect; // retangle of the grid contaning the items |
|
1588 |
|
1589 // 1. Get the layout |
|
1590 |
|
1591 // Get the parent rect |
|
1592 TRect mainPaneRect; |
|
1593 if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, |
|
1594 mainPaneRect)) |
|
1595 { |
|
1596 mainPaneRect = iAvkonAppUi->ClientRect(); |
|
1597 } |
|
1598 |
|
1599 // Calculate the layout of the whole popup with the biggest possible -> 0 |
|
1600 // Dialog layout, check variety first |
|
1601 |
|
1602 // Get the layout rect of the dialog |
|
1603 |
|
1604 // Check variety first |
|
1605 TAknLayoutScalableParameterLimits iconMapDialogVariety = |
|
1606 AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits(); |
|
1607 |
|
1608 TInt maxVariety = iconMapDialogVariety.LastVariety(); |
|
1609 |
|
1610 // Check the CBA, if the orientation is not landscape |
|
1611 // there is not so much varieties |
|
1612 AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation(); |
|
1613 TInt maxVarietyOffset = 0; // the offset for the certain cba location variety |
|
1614 TInt varietyOffset = maxVariety + 1; // the number of varieties |
|
1615 |
|
1616 // landscape variety number must be calculated offset == number of varieties |
|
1617 // same applies to the variety number for the biggest sized layout for the variety |
|
1618 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
1619 { |
|
1620 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety |
|
1621 } |
|
1622 |
|
1623 if (location == AknLayoutUtils::EAknCbaLocationRight) |
|
1624 { |
|
1625 maxVarietyOffset = varietyOffset; |
|
1626 } |
|
1627 else if (location == AknLayoutUtils::EAknCbaLocationLeft) |
|
1628 { |
|
1629 maxVarietyOffset = varietyOffset + varietyOffset; // 2* |
|
1630 } |
|
1631 |
|
1632 TAknLayoutRect popupGridLayRect; |
|
1633 popupGridLayRect.LayoutRect(mainPaneRect, |
|
1634 AknLayoutScalable_Avkon::popup_grid_graphic_window( |
|
1635 maxVarietyOffset)); |
|
1636 |
|
1637 // Get the layout of the actual icon grid with scrollbar |
|
1638 TAknLayoutRect gridWithScrollLayRect; |
|
1639 gridWithScrollLayRect.LayoutRect(popupGridLayRect.Rect(), |
|
1640 AknLayoutScalable_Avkon::listscroll_popup_graphic_pane()); |
|
1641 |
|
1642 // Then the grid area without scrollbar |
|
1643 // NOTE: The grid with scroll bar is used as reference |
|
1644 TAknLayoutRect gridLayRect; |
|
1645 gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(), |
|
1646 AknLayoutScalable_Avkon::grid_graphic_popup_pane(0)); |
|
1647 |
|
1648 // Different parent if SCT inside editing menu. |
|
1649 TRect rect = Rect(); |
|
1650 gridRect = gridLayRect.Rect(); |
|
1651 // cell size, AGAIN 7 item |
|
1652 TAknLayoutRect cellLayRect; |
|
1653 cellLayRect.LayoutRect(gridRect, |
|
1654 AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 0, 0)); |
|
1655 |
|
1656 cellRect = cellLayRect.Rect(); |
|
1657 |
|
1658 // 2. Calculate width related |
|
1659 // - item width |
|
1660 // - max number of columns |
|
1661 |
|
1662 // Width of the items area |
|
1663 TInt gridWidth = gridRect.Width(); |
|
1664 |
|
1665 // Width of one item |
|
1666 TInt cellWidth = cellRect.Width(); |
|
1667 |
|
1668 // ensure the item width and store it |
|
1669 TAknLayoutRect secondCellLayRect; |
|
1670 secondCellLayRect.LayoutRect(gridRect, |
|
1671 AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 1, 0)); |
|
1672 |
|
1673 iGridItemWidth = secondCellLayRect.Rect().iTl.iX |
|
1674 - cellLayRect.Rect().iTl.iX; |
|
1675 |
|
1676 if (iGridItemWidth < 0) |
|
1677 { |
|
1678 // The result is negative with lay file data if the layout is mirrored. |
|
1679 iGridItemWidth = -iGridItemWidth; |
|
1680 } |
|
1681 |
|
1682 // Calculate the amount of columns |
|
1683 iMaxColumns = gridWidth / cellWidth; |
|
1684 |
|
1685 // 2. Calculate height related |
|
1686 // - item height |
|
1687 // - max number of rows |
|
1688 |
|
1689 // Get the grid height |
|
1690 // NOTE: in landscape the LAF is wrong so use the main panes height |
|
1691 TInt gridHeight = gridRect.Height(); |
|
1692 |
|
1693 // get the item height |
|
1694 TInt cellHeight = cellRect.Height(); |
|
1695 |
|
1696 // calculate the number of items fitting to grid |
|
1697 Extension()->iMaxVisibleRows = 3;//gridHeight / cellHeight; |
|
1698 |
|
1699 |
|
1700 // Store the item height |
|
1701 TAknLayoutRect secondRowLayRect; |
|
1702 secondRowLayRect.LayoutRect(gridLayRect.Rect(), |
|
1703 AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 0, 1)); |
|
1704 |
|
1705 iGridItemHeight = secondRowLayRect.Rect().iTl.iY |
|
1706 - cellLayRect.Rect().iTl.iY; |
|
1707 } |
|
1708 |
|
1709 // ----------------------------------------------------------------------------- |
|
1710 // CLmkIconMap::HandleScrollEventL |
|
1711 // Handles the different scroll events so that the map reacts accordingly. |
|
1712 // ----------------------------------------------------------------------------- |
|
1713 // |
|
1714 void CLmkIconMap::HandleScrollEventL(CEikScrollBar* aScrollBar, |
|
1715 TEikScrollEvent aEventType) |
|
1716 { |
|
1717 TBool update = EFalse; |
|
1718 |
|
1719 switch (aEventType) |
|
1720 { |
|
1721 case EEikScrollUp: |
|
1722 case EEikScrollPageUp: |
|
1723 { |
|
1724 // nothing done if we are already on the first page. |
|
1725 if (iFirstVisibleRow != 0) |
|
1726 { |
|
1727 iFirstVisibleRow -= Extension()->iMaxVisibleRows; |
|
1728 update = ETrue; |
|
1729 } |
|
1730 UpdateScrollIndicatorL(); |
|
1731 } |
|
1732 break; |
|
1733 case EEikScrollDown: |
|
1734 case EEikScrollPageDown: |
|
1735 { |
|
1736 // nothing done if we are already on the last page. |
|
1737 if (iFirstVisibleRow != (iRows / Extension()->iMaxVisibleRows) |
|
1738 * Extension()->iMaxVisibleRows) |
|
1739 { |
|
1740 iFirstVisibleRow += Extension()->iMaxVisibleRows; |
|
1741 update = ETrue; |
|
1742 } |
|
1743 UpdateScrollIndicatorL(); |
|
1744 } |
|
1745 break; |
|
1746 case EEikScrollThumbDragVert: |
|
1747 { |
|
1748 TInt thumbPosition; |
|
1749 TInt halfPage = Extension()->iMaxVisibleRows / 2; |
|
1750 // Ask which type of scrollbar is shown |
|
1751 //CAknAppUi* appUi = iAvkonAppUi; |
|
1752 TBool isDoubleSpan = CEikScrollBarFrame::EDoubleSpan |
|
1753 == iSBFrame->TypeOfVScrollBar(); |
|
1754 if (isDoubleSpan) |
|
1755 { |
|
1756 thumbPosition |
|
1757 = static_cast<const TAknDoubleSpanScrollBarModel*> (aScrollBar->Model())->FocusPosition(); |
|
1758 } |
|
1759 else |
|
1760 { |
|
1761 thumbPosition = aScrollBar->Model()->iThumbPosition; |
|
1762 } |
|
1763 |
|
1764 // If the slider is in the range of less then a half page from a possible correct thumb position. |
|
1765 // thus 0 <= iFirstVisibleRow - thumbPosition < halfPage. Or in the other direction: |
|
1766 // 0 <= thumbPosition - iFirstVisibleRow < halfPage |
|
1767 if (!((0 <= iFirstVisibleRow - thumbPosition && iFirstVisibleRow |
|
1768 - thumbPosition < halfPage) || (0 <= thumbPosition |
|
1769 - iFirstVisibleRow && thumbPosition - iFirstVisibleRow |
|
1770 < halfPage))) |
|
1771 { |
|
1772 TReal toRound = thumbPosition |
|
1773 / (TReal) Extension()->iMaxVisibleRows; |
|
1774 if (toRound * 2 > (TInt) toRound * 2 + 1) |
|
1775 { |
|
1776 toRound++; |
|
1777 } |
|
1778 iFirstVisibleRow = (TInt) toRound |
|
1779 * Extension()->iMaxVisibleRows; |
|
1780 iCurrentPage = (iFirstVisibleRow |
|
1781 / Extension()->iMaxVisibleRows) + 1; |
|
1782 update = ETrue; |
|
1783 } |
|
1784 } |
|
1785 break; |
|
1786 case EEikScrollThumbReleaseVert: |
|
1787 { |
|
1788 UpdateScrollIndicatorL(); |
|
1789 } |
|
1790 break; |
|
1791 case EEikScrollLeft: // flow through |
|
1792 case EEikScrollRight: // flow through |
|
1793 case EEikScrollPageLeft: // flow through |
|
1794 case EEikScrollPageRight: // flow through |
|
1795 case EEikScrollThumbDragHoriz: // flow through |
|
1796 case EEikScrollThumbReleaseHoriz: // flow through |
|
1797 // do nothing |
|
1798 break; |
|
1799 default: |
|
1800 // do nothing |
|
1801 break; |
|
1802 } |
|
1803 |
|
1804 // If we have moved down to the last page we check that the cursor is in a place where it can be |
|
1805 // drawn. |
|
1806 if (iFirstVisibleRow == (iRows / Extension()->iMaxVisibleRows) |
|
1807 * Extension()->iMaxVisibleRows) |
|
1808 { |
|
1809 // the old cursor is set to a "safe" position where it at least can be. |
|
1810 iOldCursorPos.iX = 0; |
|
1811 iOldCursorPos.iY = 0; |
|
1812 // if the last page has only one line which isn't filled complitely. |
|
1813 if (iConsArray->Count() % iMaxColumns - 1 < iCursorPos.iX && iRows |
|
1814 % Extension()->iMaxVisibleRows == 1) |
|
1815 { |
|
1816 TInt xVal = iConsArray->Count() % iMaxColumns - 1; |
|
1817 if (xVal >= 0) |
|
1818 iCursorPos.iX = xVal; |
|
1819 } |
|
1820 // If the cursor is in a position where it would go unto a spot with out |
|
1821 // a icon when scrolled. |
|
1822 if (iCursorPos.iY + iFirstVisibleRow >= iRows) |
|
1823 { |
|
1824 if (iConsArray->Count() % iMaxColumns > iCursorPos.iX) |
|
1825 { |
|
1826 TInt yVal = iRows - 1 - iFirstVisibleRow; |
|
1827 if (yVal >= 0) |
|
1828 iCursorPos.iY = yVal; |
|
1829 } |
|
1830 else |
|
1831 { |
|
1832 TInt yVal = iRows - 2 - iFirstVisibleRow; |
|
1833 if (yVal >= 0) |
|
1834 iCursorPos.iY = yVal; |
|
1835 } |
|
1836 } |
|
1837 // If the cursor is actually on the last row, but is still in the |
|
1838 // area where there is now icons. (the rest of the last row) |
|
1839 if (iConsArray->Count() <= (iFirstVisibleRow + iCursorPos.iY) |
|
1840 * iMaxColumns + iCursorPos.iX && iCursorPos.iY |
|
1841 + iFirstVisibleRow + 1 == iRows) |
|
1842 { |
|
1843 iCursorPos.iY--; |
|
1844 } |
|
1845 // if the corrections did not help and the cursor is in the area |
|
1846 // where there is a valid row, but no icons anymore |
|
1847 } |
|
1848 |
|
1849 // to avoid flicker we draw only if there really was something new to draw. |
|
1850 if (update) |
|
1851 { |
|
1852 if (Extension()->iObserver) |
|
1853 { |
|
1854 Extension()->iObserver->HandleControlEventL(this, |
|
1855 MCoeControlObserver::EEventRequestFocus); |
|
1856 } |
|
1857 DrawDeferred(); |
|
1858 } |
|
1859 } |
|
1860 |
|
1861 // ----------------------------------------------------------------------------- |
|
1862 // CLmkIconMap::Extension |
|
1863 // Asserts that extension object has been created. |
|
1864 // ----------------------------------------------------------------------------- |
|
1865 // |
|
1866 CLmkIconMapExtension* CLmkIconMap::Extension() const |
|
1867 { |
|
1868 __ASSERT_ALWAYS(iExtension, Panic(KLmkPanicNullPointer)); |
|
1869 return iExtension; |
|
1870 } |
|
1871 |
|
1872 #ifdef RD_SCALABLE_UI_V2 |
|
1873 //-------------------------------------------------------------------------- |
|
1874 // void CLmkIconMap::HandlePointerEventL() |
|
1875 //-------------------------------------------------------------------------- |
|
1876 void CLmkIconMap::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
1877 { |
|
1878 if (AknLayoutUtils::PenEnabled()) |
|
1879 { |
|
1880 TInt newGridX; // For the whole |
|
1881 TInt newGridY; // For the whole grid. |
|
1882 TInt yInPixels = aPointerEvent.iPosition.iY - iGridTopLeft.iY; |
|
1883 newGridY = yInPixels / iGridItemHeight; |
|
1884 if ((aPointerEvent.iPosition.iX - iGridTopLeft.iX) < 0) |
|
1885 { |
|
1886 newGridX = -1; |
|
1887 } |
|
1888 else |
|
1889 { |
|
1890 newGridX = (aPointerEvent.iPosition.iX - iGridTopLeft.iX) |
|
1891 / iGridItemWidth; |
|
1892 } |
|
1893 TInt previousRows = (iRows / iExtension->iMaxVisibleRows) |
|
1894 * iExtension->iMaxVisibleRows; |
|
1895 TUint lastRowsLength = iConsArray->Count() % iMaxColumns; |
|
1896 |
|
1897 // The pointer has been set down or dragged into the area of the grid. (it might be in |
|
1898 // the "white space" at the end of the grid) |
|
1899 if ((yInPixels >= 0 && yInPixels < iGridItemHeight |
|
1900 * iExtension->iMaxVisibleRows) && |
|
1901 // When the pointer is in rows except the recent icon row |
|
1902 ((((newGridY + iFirstVisibleRow) != 0) && newGridX |
|
1903 < iMaxColumns && newGridX >= 0) || |
|
1904 // When the pointer is in the recent icon row |
|
1905 ((newGridY + iFirstVisibleRow == 0) && (newGridX |
|
1906 < iMaxColumns)))) |
|
1907 { |
|
1908 // For any action to be taken, the pointer event must either be a Button1Down or a drag event |
|
1909 // which has originated from a Button1Down in to the grid. |
|
1910 if (aPointerEvent.iType == TPointerEvent::EButton1Down) |
|
1911 { |
|
1912 TUint globalY = newGridY + iFirstVisibleRow; |
|
1913 // The user tapps a cell which has no icon. it is ignored. |
|
1914 if (iConsArray->Count() > globalY * iMaxColumns + newGridX) |
|
1915 { |
|
1916 //If icon is already selected then on single tap it should change the icon. |
|
1917 if (iCursorPos.iY == newGridY && iCursorPos.iX |
|
1918 == newGridX) |
|
1919 { |
|
1920 #ifdef RD_TACTILE_FEEDBACK |
|
1921 // The user tapps a cell which has icon, selection has been accepted |
|
1922 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
1923 if (feedback) |
|
1924 { |
|
1925 feedback->InstantFeedback(this, |
|
1926 ETouchFeedbackBasic); |
|
1927 } |
|
1928 #endif //RD_TACTILE_FEEDBACK |
|
1929 //iIsChangeIcon = ETrue; |
|
1930 } |
|
1931 else if (iCursorPos.iX + (iCursorPos.iY |
|
1932 + iFirstVisibleRow) * iMaxColumns |
|
1933 < iConsArray->Count()) |
|
1934 { |
|
1935 #ifdef RD_TACTILE_FEEDBACK |
|
1936 // The user tapps a cell which has icon, send feedback if position has changed |
|
1937 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
1938 const TBool feedbackNeeded = (iCursorPos.iY |
|
1939 != newGridY) || (iCursorPos.iX != newGridX); |
|
1940 if (feedback && feedbackNeeded) |
|
1941 { |
|
1942 feedback->InstantFeedback(this, |
|
1943 ETouchFeedbackBasic); |
|
1944 } |
|
1945 #endif //RD_TACTILE_FEEDBACK |
|
1946 iOldCursorPos = iCursorPos; |
|
1947 iCursorPos.iY = newGridY; |
|
1948 iCursorPos.iX = newGridX; |
|
1949 DrawCursor(); |
|
1950 } |
|
1951 else |
|
1952 { |
|
1953 iOldCursorPos = iCursorPos; |
|
1954 iCursorPos.iY = newGridY; |
|
1955 iCursorPos.iX = newGridX; |
|
1956 DrawCursor(); |
|
1957 } |
|
1958 } |
|
1959 } |
|
1960 else if (aPointerEvent.iType == TPointerEvent::EDrag) |
|
1961 { |
|
1962 //Handle drag event only if the icon is not already selected, if already selected then do nothing for EDrag event |
|
1963 if (iCursorPos.iY != newGridY || iCursorPos.iX != newGridX) |
|
1964 { |
|
1965 //iIsChangeIcon = EFalse; |
|
1966 TUint globalY = newGridY + iFirstVisibleRow; |
|
1967 // The user tapps a cell which has no icon. it is ignored. |
|
1968 if (iConsArray->Count() > globalY * iMaxColumns |
|
1969 + newGridX) |
|
1970 { |
|
1971 if (iCursorPos.iX |
|
1972 + (iCursorPos.iY + iFirstVisibleRow) |
|
1973 * iMaxColumns < iConsArray->Count()) |
|
1974 { |
|
1975 #ifdef RD_TACTILE_FEEDBACK |
|
1976 // While dragging cell is changed, give sensitive feedback |
|
1977 MTouchFeedback* feedback = |
|
1978 MTouchFeedback::Instance(); |
|
1979 const TBool feedbackNeeded = (iCursorPos.iY |
|
1980 != newGridY) || (iCursorPos.iX |
|
1981 != newGridX); |
|
1982 if (feedback && feedbackNeeded) |
|
1983 { |
|
1984 feedback->InstantFeedback(this, |
|
1985 ETouchFeedbackSensitive); |
|
1986 } |
|
1987 #endif //RD_TACTILE_FEEDBACK |
|
1988 iOldCursorPos = iCursorPos; |
|
1989 iCursorPos.iY = newGridY; |
|
1990 iCursorPos.iX = newGridX; |
|
1991 DrawCursor(); |
|
1992 } |
|
1993 else |
|
1994 { |
|
1995 iOldCursorPos.iX = 0; |
|
1996 iOldCursorPos.iY = 0; |
|
1997 } |
|
1998 } |
|
1999 } |
|
2000 |
|
2001 } |
|
2002 else if (aPointerEvent.iType == TPointerEvent::EButton1Up) |
|
2003 { |
|
2004 //if (iIsChangeIcon) |
|
2005 |
|
2006 { |
|
2007 iExtension->iObserver->HandleControlEventL(this, |
|
2008 MCoeControlObserver::EEventStateChanged); |
|
2009 //iIsChangeIcon = EFalse; |
|
2010 } |
|
2011 } |
|
2012 } |
|
2013 // Events: Drag and repeat pointer events which are not on the scrollbar are handled here. |
|
2014 |
|
2015 else if (iConsArray->Count() > iMaxColumns |
|
2016 * iExtension->iMaxVisibleRows && newGridX < iMaxColumns |
|
2017 && newGridX >= 0 && newGridY < iExtension->iMaxVisibleRows |
|
2018 && newGridY >= 0) |
|
2019 { |
|
2020 TRect ignoreUpRect(TPoint(KMinTInt, KMinTInt), TPoint(KMaxTInt, |
|
2021 iGridTopLeft.iY)); |
|
2022 TRect ignoreDownRect(TPoint(KMinTInt, (iGridTopLeft.iY |
|
2023 + iGridItemHeight * iExtension->iMaxVisibleRows)), |
|
2024 TPoint(KMaxTInt, KMaxTInt)); |
|
2025 // Drag events |
|
2026 if (aPointerEvent.iType == TPointerEvent::EDrag |
|
2027 || aPointerEvent.iType == TPointerEvent::EButtonRepeat) |
|
2028 { |
|
2029 // The pointer is dragged upwards from map |
|
2030 if (aPointerEvent.iPosition.iY < iGridTopLeft.iY |
|
2031 && aPointerEvent.iPosition.iX < iGridTopLeft.iX) //scroll up |
|
2032 { |
|
2033 // focus on first page |
|
2034 if (iFirstVisibleRow == 0) |
|
2035 { |
|
2036 iFirstVisibleRow = previousRows; |
|
2037 // if the last page contains only one partial row. |
|
2038 if (lastRowsLength - 1 < iCursorPos.iX && iRows |
|
2039 % iExtension->iMaxVisibleRows == 1) |
|
2040 { |
|
2041 iCursorPos.iX = lastRowsLength - 1; |
|
2042 } |
|
2043 } |
|
2044 // focus on some other page than first |
|
2045 else |
|
2046 { |
|
2047 iFirstVisibleRow -= iExtension->iMaxVisibleRows; |
|
2048 } |
|
2049 // For odd reason the user has been able to induce upward dragging with out moving |
|
2050 // up through the grid. |
|
2051 if (iCursorPos.iY + iExtension->iMaxVisibleRows |
|
2052 != iFirstVisibleRow) |
|
2053 { |
|
2054 iCursorPos.iY = 0; |
|
2055 } |
|
2056 UpdateScrollIndicatorL(); |
|
2057 if (iExtension->iObserver) |
|
2058 { |
|
2059 iExtension->iObserver->HandleControlEventL(this, |
|
2060 MCoeControlObserver::EEventRequestFocus); |
|
2061 } |
|
2062 DrawDeferred(); |
|
2063 } |
|
2064 // the pointer is dragged downwards from the map. |
|
2065 else if (yInPixels >= iGridItemHeight |
|
2066 * iExtension->iMaxVisibleRows) //scroll down |
|
2067 { |
|
2068 // The focus is on the last page |
|
2069 if (iFirstVisibleRow == previousRows) |
|
2070 { |
|
2071 iFirstVisibleRow = 0; |
|
2072 iCursorPos.iY = iExtension->iMaxVisibleRows - 1; |
|
2073 } |
|
2074 // The focus is on some other page than the last one. |
|
2075 else |
|
2076 { |
|
2077 iFirstVisibleRow += iExtension->iMaxVisibleRows; |
|
2078 // if the next page is the last page |
|
2079 if (iFirstVisibleRow == previousRows) |
|
2080 { |
|
2081 // the old cursor is set to a "safe" position where it at least can be. |
|
2082 iOldCursorPos.iX = 0; |
|
2083 iOldCursorPos.iY = 0; |
|
2084 |
|
2085 // if the last page has only one line which isn't filled complitely. |
|
2086 if (lastRowsLength - 1 < iCursorPos.iX && iRows |
|
2087 % iExtension->iMaxVisibleRows == 1) |
|
2088 { |
|
2089 iCursorPos.iX = lastRowsLength - 1; |
|
2090 } |
|
2091 // If the cursor is in a position where it would go unto a spot with out |
|
2092 // a icon when scrolled. |
|
2093 if (lastRowsLength > iCursorPos.iX) |
|
2094 { |
|
2095 // |
|
2096 iCursorPos.iY = iRows - 1 - iFirstVisibleRow; |
|
2097 } |
|
2098 else |
|
2099 { |
|
2100 // |
|
2101 iCursorPos.iY = iRows - 2 - iFirstVisibleRow; |
|
2102 } |
|
2103 } |
|
2104 } |
|
2105 UpdateScrollIndicatorL(); |
|
2106 if (iExtension->iObserver) |
|
2107 { |
|
2108 iExtension->iObserver->HandleControlEventL(this, |
|
2109 MCoeControlObserver::EEventRequestFocus); |
|
2110 } |
|
2111 DrawDeferred(); |
|
2112 } |
|
2113 } |
|
2114 } |
|
2115 |
|
2116 else // For a non window owning scrollbar. |
|
2117 { |
|
2118 CCoeControl::HandlePointerEventL(aPointerEvent); |
|
2119 } |
|
2120 } |
|
2121 } |
|
2122 |
|
2123 // ----------------------------------------------------------------------------- |
|
2124 // CLmkIconMap::SetObserver |
|
2125 // Sets the observer. |
|
2126 // ----------------------------------------------------------------------------- |
|
2127 // |
|
2128 void CLmkIconMap::SetObserver( MCoeControlObserver* aObserver ) |
|
2129 { |
|
2130 if (iExtension) |
|
2131 { |
|
2132 iExtension->iObserver = aObserver; |
|
2133 } |
|
2134 } |
|
2135 |
|
2136 #endif //RD_SCALABLE_UI_V2 |
|
2137 // End of File |