|
1 /* |
|
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <barsread.h> |
|
20 #include <coemain.h> |
|
21 #include <eikenv.h> |
|
22 #include <eikcapc.h> |
|
23 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
24 #include <eikfctry.h> |
|
25 #else |
|
26 #include <eikfctry.h> |
|
27 #include <uikon/eikctrlstatus.h> |
|
28 #endif |
|
29 #include <eikcapca.h> |
|
30 #include <eikedwin.h> |
|
31 #include <eikappui.h> |
|
32 #include <eikdpage.h> |
|
33 #include <eikdpsel.h> |
|
34 #include <eikdialg.pan> |
|
35 #include <eikform.pan> |
|
36 #include <eikon.hrh> |
|
37 #include <eikdialogext.h> |
|
38 #include <eikseced.h> |
|
39 #include <eikmfne.h> |
|
40 #include <eikfpne.h> |
|
41 #include <avkon.hrh> |
|
42 #include <avkon.rsg> |
|
43 #include <AknUtils.h> |
|
44 #include <eikscrlb.h> |
|
45 #include <AknsDrawUtils.h> |
|
46 #include <AknsUtils.h> |
|
47 #include <skinlayout.cdl.h> |
|
48 #include <aknlayoutscalable_avkon.cdl.h> |
|
49 #include "EIKFANIM.H" |
|
50 |
|
51 #include <touchfeedback.h> |
|
52 |
|
53 #include <AknTasHook.h> // for testability hooks |
|
54 #include "aknformphysics.h" |
|
55 #include "aknrecordinggc.h" |
|
56 #include <aknphysics.h> |
|
57 #include <aknappui.h> |
|
58 #include <aknPriv.hrh> |
|
59 |
|
60 // |
|
61 // Global constants. |
|
62 // |
|
63 |
|
64 const TInt KSpaceFromTitle=0 ; |
|
65 const TInt KSpaceFromBottom=0 ; |
|
66 const TInt KPageArrayGranularity=4; |
|
67 const TInt KLineArrayGranularity=4; |
|
68 |
|
69 /* |
|
70 * The following set of static functions return value which have been hard coded from the Series 60 Skins LAF v2.0 |
|
71 * If a layout DLL becomes available the hard-coded values may be replaced with equivalent Macros. |
|
72 * NOTE THAT THESE ARE COPIES OF FUNCTIONS IN EIKCAPC.CPP |
|
73 */ |
|
74 |
|
75 LOCAL_D TRect EditFrameTopLeftRect( const TRect& aParentRect ) |
|
76 {// Skins LAF table 5.24 Line 2 |
|
77 TAknLayoutRect topLeft ; |
|
78 topLeft.LayoutRect( aParentRect, SkinLayout::Input_field_skin_placing__general__Line_2() ); |
|
79 return topLeft.Rect() ; |
|
80 } |
|
81 |
|
82 LOCAL_D TRect EditFrameBottomRightRect( const TRect& aParentRect ) |
|
83 {// Skins LAF table 5.24 Line 5 |
|
84 TAknWindowLineLayout l( SkinLayout::Input_field_skin_placing__general__Line_5() ); |
|
85 TAknLayoutRect layoutRect; |
|
86 layoutRect.LayoutRect( aParentRect, l ); |
|
87 TRect rectInputField( layoutRect.Rect() ); |
|
88 |
|
89 return rectInputField; |
|
90 } |
|
91 |
|
92 NONSHARABLE_CLASS(CDialogPageExtension) : public CBase |
|
93 { |
|
94 public: |
|
95 enum TFlags |
|
96 { |
|
97 ELineHandlerCalled |
|
98 }; |
|
99 static CDialogPageExtension* NewL(); |
|
100 ~CDialogPageExtension(); |
|
101 |
|
102 void Feedback( CEikDialogPage* aControl, TTouchLogicalFeedback aFeedback ) const; |
|
103 /** |
|
104 * Produces vibra-only feedback. Event filtering by pointer event is used.. |
|
105 */ |
|
106 void SilentFeedback( CEikDialogPage* aDPage, |
|
107 TTouchLogicalFeedback aFeedback, |
|
108 const TPointerEvent& aPointerEvent ) const; |
|
109 |
|
110 void HandleFormFeedback( CEikDialogPage* aControl, const TPointerEvent& aPointerEvent, TInt aTouchedLineIndex, TInt aCurrentLine ); |
|
111 |
|
112 protected: |
|
113 void ConstructL(); |
|
114 |
|
115 private: |
|
116 CDialogPageExtension(); |
|
117 CDialogPageExtension(const CDialogPageExtension& aExtension); |
|
118 |
|
119 public: |
|
120 TInt iPopFieldEvents; |
|
121 TBool iExternalScrollbar; |
|
122 TBool iIsDoubleQuery; |
|
123 TBool iFocusedClicked; |
|
124 TInt iPreviousThumbPosition; |
|
125 TBool iPreviousThumbDirection; |
|
126 MTouchFeedback* iFeedback; |
|
127 TBitFlags iFlags; |
|
128 /** |
|
129 * @c iDestroyedPtr is used for the object destruction check. |
|
130 * If it has non-null value, the destruction check is turned on, and |
|
131 * the value points to a local boolean variable that keeps the destroyed state. |
|
132 */ |
|
133 TBool* iDestroyedPtr; |
|
134 |
|
135 TPoint iDragStartPosition; |
|
136 TPoint iLastPointerPos; |
|
137 TTime iStartTime; |
|
138 CAknRecordingGc* iRecordingGc; |
|
139 TBool iHandlingScrollEvent; |
|
140 CPeriodic* iHighlightTimer; |
|
141 TInt iLastTouchedLine; |
|
142 TPoint iSynchronizedPosition; |
|
143 TBool iScrolling; |
|
144 TBool iScrolled; |
|
145 TBool iInitialLayoutDone; |
|
146 TBool iSetInitialFocusDone; |
|
147 TBool iHandlingResourceChange; |
|
148 TInt iCapturingItem; |
|
149 // record the center point Y value of current view when touch down an item |
|
150 TInt iOldCenterY; |
|
151 // top item in current view, -1 if item's Y is negative |
|
152 TInt iTopItem; |
|
153 // bottom item in current view, fields count when Y is larger than |
|
154 // the last item's Y |
|
155 TInt iBottomItem; |
|
156 |
|
157 /** |
|
158 * Boolean used to check if application is single touch compatible. |
|
159 */ |
|
160 TBool iUsesSingleClick; |
|
161 // It is used to distinguish if the focus item has changed. |
|
162 TBool iFocusItemChanged; |
|
163 }; |
|
164 |
|
165 CDialogPageExtension::CDialogPageExtension() |
|
166 { |
|
167 } |
|
168 |
|
169 CDialogPageExtension* CDialogPageExtension::NewL() |
|
170 { |
|
171 CDialogPageExtension* extension = new (ELeave) CDialogPageExtension(); |
|
172 CleanupStack::PushL(extension); |
|
173 extension->ConstructL(); |
|
174 CleanupStack::Pop(extension); //extension |
|
175 |
|
176 return extension; |
|
177 } |
|
178 |
|
179 CDialogPageExtension::~CDialogPageExtension() |
|
180 { |
|
181 delete iHighlightTimer; |
|
182 delete iRecordingGc; |
|
183 |
|
184 if( iDestroyedPtr ) |
|
185 { |
|
186 // Mark the object as destroyed. |
|
187 *iDestroyedPtr = ETrue; |
|
188 iDestroyedPtr = NULL; |
|
189 } |
|
190 } |
|
191 |
|
192 CDialogPageExtension::CDialogPageExtension(const CDialogPageExtension& /*aExtension*/) |
|
193 { |
|
194 } |
|
195 |
|
196 void CDialogPageExtension::ConstructL() |
|
197 { |
|
198 iFeedback = MTouchFeedback::Instance(); |
|
199 iHighlightTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
200 iCapturingItem = KErrNotFound; |
|
201 } |
|
202 |
|
203 void CDialogPageExtension::HandleFormFeedback( |
|
204 CEikDialogPage* aDPage, |
|
205 const TPointerEvent& aPointerEvent, |
|
206 TInt aTouchedLineIndex, |
|
207 TInt aCurrentLine ) |
|
208 { |
|
209 // note, that iFormControl is checked in Feedback() |
|
210 if ( aPointerEvent.iType == TPointerEvent::EButton1Down && |
|
211 aCurrentLine != aTouchedLineIndex && aDPage->LineOnPageOrNull( 0 ) ) |
|
212 { |
|
213 // feedback for edit/view mode form, when non-focused line is clicked |
|
214 // feedback for focused item is responsibility of the item |
|
215 // no feedback with focus change when single click is enabled |
|
216 if ( !iUsesSingleClick ) |
|
217 { |
|
218 Feedback( aDPage, ETouchFeedbackSensitiveList ); |
|
219 } |
|
220 iFocusItemChanged = ETrue; |
|
221 } |
|
222 |
|
223 else if ( aPointerEvent.iType == TPointerEvent::EButton1Down && |
|
224 aTouchedLineIndex == aCurrentLine && aDPage->LineOnPageOrNull( 0 ) ) |
|
225 { |
|
226 // Feedback for view mode form, when focused item is |
|
227 // clicked. Basically same case as for msk simulation later on |
|
228 // the function, but on pointer |
|
229 // down. iExtension->iFocusedClicked is not valid here, since |
|
230 // it can't be known in this phase whether user drags pointer |
|
231 // away. |
|
232 Feedback( aDPage, ETouchFeedbackList ); |
|
233 iFocusItemChanged = EFalse; |
|
234 } |
|
235 |
|
236 else if ( aPointerEvent.iType == TPointerEvent::EButton1Up && |
|
237 aDPage->LineOnPageOrNull( 0 ) ) |
|
238 {// when focus changed, it should not send feedback on up event. |
|
239 //when up event comes, aTouchedLineIndex always equal to aCurrentLine |
|
240 if ( !iFocusItemChanged ) |
|
241 { |
|
242 SilentFeedback( aDPage, ETouchFeedbackList, aPointerEvent ); |
|
243 } |
|
244 } |
|
245 } |
|
246 |
|
247 void CDialogPageExtension::Feedback( CEikDialogPage* aDPage, |
|
248 TTouchLogicalFeedback aFeedback ) const |
|
249 { |
|
250 if ( aDPage |
|
251 && aDPage->IsForm() |
|
252 && iFeedback |
|
253 && !aDPage->IsDimmed() |
|
254 && aDPage->IsVisible() ) |
|
255 { |
|
256 iFeedback->InstantFeedback( aFeedback ); |
|
257 } |
|
258 } |
|
259 |
|
260 void CDialogPageExtension::SilentFeedback( CEikDialogPage* aDPage, |
|
261 TTouchLogicalFeedback aFeedback, |
|
262 const TPointerEvent& aPointerEvent ) const |
|
263 { |
|
264 if ( aDPage |
|
265 && aDPage->IsForm() |
|
266 && iFeedback |
|
267 && !aDPage->IsDimmed() |
|
268 && aDPage->IsVisible() ) |
|
269 { |
|
270 iFeedback->InstantFeedback( aDPage, aFeedback, ETouchFeedbackVibra, aPointerEvent ); |
|
271 } |
|
272 } |
|
273 |
|
274 class CAknPaneScroll : public CBase |
|
275 { |
|
276 public: |
|
277 enum TScrollChangeType |
|
278 { |
|
279 ENoChange = 0, |
|
280 ETopChanged = 1, |
|
281 EBottomChanged = 2, |
|
282 ESizeChanged = 4, |
|
283 EFocusChanged = 8 |
|
284 }; |
|
285 CAknPaneScroll(CCoeControl* /*ctrl*/) : iTop(0), iMiddle(-1), iBottom(-1) { } |
|
286 void SetLines(CEikCapCArray *aLines) { iLines = aLines; } |
|
287 void SetOutsideRect(TRect aRect); // this is list_form_gen_pane |
|
288 TScrollChangeType ExposeLine(TInt aLine, TBool aShowWholeLine=ETrue); |
|
289 TInt Top() const {return iTop; } |
|
290 TInt Middle() const {return iMiddle; } |
|
291 TInt Bottom() const {return iBottom; } |
|
292 private: |
|
293 TRect iOutsideRect; |
|
294 CEikCapCArray *iLines; |
|
295 TInt iTop, iMiddle, iBottom; |
|
296 TInt iOldTop, iOldMiddle, iOldBottom; |
|
297 TInt iOldFocus; |
|
298 }; |
|
299 |
|
300 CAknPaneScroll::TScrollChangeType CAknPaneScroll::ExposeLine(TInt aLine, TBool /*aShowWholeLine*/) |
|
301 { |
|
302 if (aLine < 0 || aLine >= iLines->Count()) return ENoChange; |
|
303 |
|
304 TInt top = iTop; |
|
305 TInt middle = iMiddle; |
|
306 TInt bottom = iBottom; |
|
307 |
|
308 TBool switchDir = iLines->CalcItemIndexes(top, middle, bottom, iOutsideRect.Size()); |
|
309 |
|
310 if (switchDir && iTop == -1) { iTop = top; iMiddle = -1; iBottom = -1; } |
|
311 if (switchDir && iBottom == -1) { iTop = -1; iMiddle = -1; iBottom = bottom; } |
|
312 if (aLine < top) { iTop = aLine; iMiddle = -1; iBottom=-1; } |
|
313 else if (aLine >= iLines->Count() - bottom) { iBottom = iLines->Count() - 1 - aLine; iMiddle = -1; iTop=-1; } |
|
314 |
|
315 TScrollChangeType change = ENoChange; |
|
316 if (iOldTop != top) { change = TScrollChangeType(change | ETopChanged); } |
|
317 if (iOldBottom != bottom) { change = TScrollChangeType(change | EBottomChanged); } |
|
318 if (iOldMiddle != middle) { change = TScrollChangeType(change | ESizeChanged); } |
|
319 if (iOldFocus != aLine) {change = TScrollChangeType(change | EFocusChanged); } |
|
320 |
|
321 iOldTop = top; |
|
322 iOldMiddle = middle; |
|
323 iOldBottom = bottom; |
|
324 iOldFocus = aLine; |
|
325 return change; |
|
326 } |
|
327 |
|
328 void CAknPaneScroll::SetOutsideRect(TRect aRect) { iOutsideRect = aRect; } |
|
329 |
|
330 // |
|
331 // CEikDialogPage. |
|
332 // |
|
333 |
|
334 CEikDialogPage::~CEikDialogPage() |
|
335 { |
|
336 AKNTASHOOK_REMOVE(); |
|
337 // Page observer needs to be nulled or an already deleted instance is |
|
338 // called when pointer up event is handled. This is valid only for dialogs |
|
339 // that have embedded virtual inputs. |
|
340 iPageObserver = NULL; |
|
341 delete iPhysics; |
|
342 delete iLines; |
|
343 delete iScroll; |
|
344 delete iExtension; |
|
345 } |
|
346 |
|
347 CEikDialogPage* CEikDialogPage::NewL(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver) |
|
348 { |
|
349 CEikDialogPage* self=CEikDialogPage::NewLC(aPageId,aViewWin,aSBFrame,aParent,aPageObserver); |
|
350 CleanupStack::Pop(); |
|
351 return self; |
|
352 } |
|
353 |
|
354 void CEikDialogPage::CommonConstructCodeBetweenNewL(CEikDialogPage& aDialogPage, const CEikDialogPageContainer& aParent) |
|
355 { |
|
356 /* |
|
357 Added the next line as normal window heirarchy does not hold for dialogs, so the |
|
358 container window mechanism cannot be used to find the menu / CBA, which is used |
|
359 in the MOP system for scrollers. |
|
360 */ |
|
361 aDialogPage.SetPageContainer(&aParent); |
|
362 aDialogPage.ConstructL(); |
|
363 aDialogPage.CopyControlContextFrom(&aParent); |
|
364 }; |
|
365 |
|
366 CEikDialogPage* CEikDialogPage::NewLC(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver) |
|
367 { |
|
368 CEikDialogPage* self=new(ELeave) CEikDialogPage(aPageId,aViewWin,aSBFrame,aPageObserver); |
|
369 CleanupStack::PushL(self); |
|
370 CommonConstructCodeBetweenNewL(*self,aParent); |
|
371 AKNTASHOOK_ADDL( self, "CEikDialogPage" ); |
|
372 return self; |
|
373 } |
|
374 |
|
375 CEikDialogPage* CEikDialogPage::NewL(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver,TResourceReader& aReader) |
|
376 { |
|
377 CEikDialogPage* self=CEikDialogPage::NewLC(aPageId,aViewWin,aSBFrame,aParent,aPageObserver,aReader); |
|
378 CleanupStack::Pop(); |
|
379 return self; |
|
380 } |
|
381 |
|
382 CEikDialogPage* CEikDialogPage::NewLC(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver,TResourceReader& aReader) |
|
383 { |
|
384 CEikDialogPage* self=new(ELeave) CEikDialogPage(aPageId,aViewWin,aSBFrame,aPageObserver); |
|
385 CleanupStack::PushL(self); |
|
386 CommonConstructCodeBetweenNewL(*self,aParent); |
|
387 self->ConstructFromResourceL(aReader); |
|
388 AKNTASHOOK_ADDL( self, "CEikDialogPage" ); |
|
389 return self; |
|
390 } |
|
391 |
|
392 CEikDialogPage::CEikDialogPage(TInt aPageId,RWindow& /*aViewWin*/, |
|
393 CEikScrollBarFrame& /*aSBFrame*/,MEikDialogPageObserver* aPageObserver) |
|
394 : iPageObserver(aPageObserver), |
|
395 iPageId(aPageId),iCurrentLine(-1) |
|
396 { |
|
397 SetBlank(); |
|
398 SetComponentsToInheritVisibility(); |
|
399 } |
|
400 |
|
401 void CEikDialogPage::ConstructL() |
|
402 { |
|
403 iLines=new(ELeave)CEikCapCArray(KLineArrayGranularity); |
|
404 SetContainerWindowL( *iPageContainer ); |
|
405 Window().SetPointerGrab(ETrue); |
|
406 Window().SetShadowDisabled(ETrue); |
|
407 Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorDialogBackground,*this)); |
|
408 iScroll = new(ELeave)CAknPaneScroll(this); |
|
409 iScroll->SetLines(iLines); |
|
410 iExtension = CDialogPageExtension::NewL(); |
|
411 } |
|
412 |
|
413 void CEikDialogPage::ConstructFromResourceL(TResourceReader& aReader, TBool aFormControl ) |
|
414 { |
|
415 iFormControl = aFormControl ; |
|
416 |
|
417 if ( IsForm() ) |
|
418 { |
|
419 if ( iAvkonAppUi ) |
|
420 { |
|
421 iExtension->iUsesSingleClick = |
|
422 iAvkonAppUi->IsSingleClickCompatible(); |
|
423 } |
|
424 |
|
425 iPhysics = CAknFormPhysics::NewL( *this, *iExtension->iRecordingGc ); |
|
426 iExtension->iRecordingGc = new ( ELeave ) CAknRecordingGc( &SystemGc() ); |
|
427 } |
|
428 |
|
429 const TInt lineCount=aReader.ReadInt16(); |
|
430 if (lineCount==EEikDlgMainPageIndirect) |
|
431 { |
|
432 TInt indirectRid=aReader.ReadInt32(); |
|
433 if (!indirectRid) |
|
434 return; |
|
435 TResourceReader indirectReader; |
|
436 iCoeEnv->CreateResourceReaderLC(indirectReader,indirectRid); |
|
437 ConstructFromResourceL(indirectReader); |
|
438 CleanupStack::PopAndDestroy(); |
|
439 return; |
|
440 } |
|
441 |
|
442 // This section modified to handle FORM structure (which contains DIALOG_LINE structs ) |
|
443 // There might be lines on the page already |
|
444 for (TInt ii=0;ii<lineCount;ii++) |
|
445 { |
|
446 CEikCaptionedControl* thisLine=ConstructLineL(aReader); |
|
447 /* |
|
448 Second argument used to be used to set previous line. This has been moved into a |
|
449 AfterAddingNewLinesL, in an attempt to group code which has to be executed together |
|
450 */ |
|
451 CleanupStack::PushL(thisLine); |
|
452 |
|
453 iLines->AppendL(thisLine); |
|
454 CleanupStack::Pop(); // thisLine |
|
455 thisLine->iIsFormControl = aFormControl ; |
|
456 if ( aFormControl ) |
|
457 { |
|
458 thisLine->GetAknLayoutValuesL() ; // should cause the control to have size. |
|
459 if ( iFormFlags ) |
|
460 thisLine->SetFormFlags( iFormFlags ) ; |
|
461 } |
|
462 // allow the caption to know the one above itself |
|
463 AfterAddingNewLinesL(iLines->LineIndexFromId(thisLine->iId)); |
|
464 } |
|
465 |
|
466 SetDensePacking( !iFormControl ) ; |
|
467 if (!iScroll) |
|
468 { |
|
469 iScroll = new(ELeave)CAknPaneScroll(this); |
|
470 } |
|
471 iScroll->SetLines(iLines); |
|
472 } |
|
473 |
|
474 void CEikDialogPage::ConstructFormFromResourceL( TResourceReader& aReader ) |
|
475 { |
|
476 iFormFlags = TInt16(aReader.ReadInt16()) ; |
|
477 iFormLayout = (iFormFlags&EEikFormUseDoubleSpacedFormat) ? EDouble : ESingle; |
|
478 ConstructFromResourceL( aReader, ETrue ) ; |
|
479 } |
|
480 |
|
481 CCoeControl* CEikDialogPage::CreateLineByTypeL(const TDesC& aCaption,TInt aLineId,TInt aControlType,TAny* aReturnValue) |
|
482 { |
|
483 ShowFocus( EFalse, EFalse ) ; // Turn the focus off the current line. |
|
484 CEikCaptionedControl* line=new(ELeave) CEikCaptionedControl; |
|
485 CleanupStack::PushL(line); |
|
486 line->SetComponentsToInheritVisibility(); |
|
487 // Try to insert line above the currently selected line. If no line is currently selected then append (TimW 22/5/00) |
|
488 // INSERTION SHOULD BE BELOW! |
|
489 |
|
490 TInt oldLine = iCurrentLine; |
|
491 |
|
492 if ( (iCurrentLine != -1) && (iCurrentLine < iLines->Count()) ) |
|
493 { |
|
494 iLines->InsertL( iCurrentLine+1, line ) ; |
|
495 ++iCurrentLine; |
|
496 } |
|
497 else |
|
498 { |
|
499 iLines->AppendL( line ) ; |
|
500 iCurrentLine = iLines->Count() - 1 ; |
|
501 } |
|
502 // used to update CaptionedControlAfter field upon adding new lines. |
|
503 CleanupStack::Pop(); // "line" is now owned by iLines. |
|
504 ConstructByTypeL(aControlType,line,this); // line owns control, dialog owns line - no need for cleanup stack. |
|
505 line->SetCaptionL(aCaption); |
|
506 |
|
507 line->iId=aLineId; |
|
508 __ASSERT_DEBUG(line->IsNonFocusing() || aLineId!=0, Panic(EEikDialogPanicFocusableLineWithIdZero)); |
|
509 line->iReturnValue=aReturnValue; |
|
510 AfterAddingNewLinesL(iCurrentLine); |
|
511 TInt targetLine = iCurrentLine; |
|
512 iCurrentLine = oldLine; |
|
513 |
|
514 ChangeFocusTo( targetLine ); |
|
515 |
|
516 // physics engine needs to be updated when lines are added after the initial layout |
|
517 UpdatePhysics(); |
|
518 |
|
519 return line->iControl; |
|
520 } |
|
521 |
|
522 CEikCaptionedControl* CEikDialogPage::ConstructLineL(TInt aResourceId) |
|
523 { |
|
524 TResourceReader resourceReader; |
|
525 iCoeEnv->CreateResourceReaderLC(resourceReader,aResourceId); |
|
526 CEikCaptionedControl* line=ConstructLineL(resourceReader); |
|
527 CleanupStack::PopAndDestroy(); // resourceReader |
|
528 return line; |
|
529 } |
|
530 |
|
531 CEikCaptionedControl* CEikDialogPage::ConstructLineL(TResourceReader& aReader) |
|
532 { |
|
533 CEikCaptionedControl* line=new(ELeave) CEikCaptionedControl; |
|
534 CleanupStack::PushL(line); |
|
535 line->iIsFormControl=iFormControl; |
|
536 line->SetComponentsToInheritVisibility(); |
|
537 TInt controlType=aReader.ReadInt16(); |
|
538 TResourceReader* reader=(&aReader); |
|
539 TInt indirectRid=0; |
|
540 if (controlType==EEikDlgItemIndirect) |
|
541 { |
|
542 indirectRid=aReader.ReadInt32(); |
|
543 TResourceReader indirectReader; |
|
544 iCoeEnv->CreateResourceReaderLC(indirectReader,indirectRid); |
|
545 controlType=indirectReader.ReadInt16(); |
|
546 reader=(&indirectReader); |
|
547 } |
|
548 |
|
549 ConstructByTypeL(controlType,line,this); |
|
550 line->ConstructFromResourceL(*reader); |
|
551 if (indirectRid) |
|
552 CleanupStack::PopAndDestroy(); |
|
553 CleanupStack::Pop(); // line |
|
554 return line; |
|
555 } |
|
556 |
|
557 void CEikDialogPage::ConstructByTypeL(TInt aType,CEikCaptionedControl* aLine,CCoeControl* aContainer) |
|
558 { |
|
559 SEikControlInfo controlInfo=EikControlFactory::CreateByTypeL(aType); |
|
560 if (!controlInfo.iControl) |
|
561 controlInfo=CreateCustomControlL(aType); |
|
562 aLine->iIsFormControl=iFormControl; |
|
563 aLine->iControl=controlInfo.iControl; |
|
564 aLine->iControlType=aType; |
|
565 aLine->SetContainerWindowL(*aContainer); |
|
566 aLine->CopyControlContextFrom(aContainer); |
|
567 aLine->SetObserver(this); |
|
568 controlInfo.iControl->SetContainerWindowL(*aContainer); |
|
569 controlInfo.iControl->SetObserver(this); |
|
570 |
|
571 // Skins requires the routine of object provider through the captioned control |
|
572 if (iFormControl) |
|
573 controlInfo.iControl->SetMopParent(aLine); |
|
574 |
|
575 controlInfo.iControl->CopyControlContextFrom(aContainer); |
|
576 |
|
577 if (controlInfo.iFlags&EEikControlHasEars) |
|
578 aLine->SetUsesEars(); |
|
579 if (controlInfo.iFlags&EEikControlIsNonFocusing) |
|
580 { |
|
581 aLine->SetNonFocusing(); |
|
582 controlInfo.iControl->SetNonFocusing(); |
|
583 } |
|
584 if (controlInfo.iFlags&EEikControlHasExtraAscent) |
|
585 aLine->SetExtraAscent(); |
|
586 if (controlInfo.iTrailerTextId) |
|
587 { |
|
588 HBufC* tmp=iCoeEnv->AllocReadResourceLC(controlInfo.iTrailerTextId); |
|
589 aLine->SetTrailerL(tmp->Des()); |
|
590 CleanupStack::PopAndDestroy(); // tmp |
|
591 } |
|
592 } |
|
593 |
|
594 SEikControlInfo CEikDialogPage::CreateCustomControlL(TInt aControlType) |
|
595 { |
|
596 ASSERT(iPageObserver); |
|
597 return iPageObserver->CreateCustomControlL(aControlType); |
|
598 } |
|
599 |
|
600 void CEikDialogPage::SetActiveL() |
|
601 { |
|
602 ActivateL(); |
|
603 MakeVisible(ETrue); |
|
604 |
|
605 if(AknLayoutUtils::PenEnabled()) |
|
606 { |
|
607 if (iFormControl && iPageContainer->ScrollBar()) |
|
608 { |
|
609 iPageContainer->ScrollBar()->SetScrollBarFrameObserver(this); |
|
610 } |
|
611 } |
|
612 |
|
613 UpdateScrollBarL(); |
|
614 MakeEdwinScrollbarsVisibleL(ETrue); |
|
615 |
|
616 const TInt numLines=iLines->Count(); |
|
617 for (TInt ii=0;ii<numLines;ii++) |
|
618 { |
|
619 CEikCaptionedControl* line=(*iLines)[ii]; |
|
620 if (line->IsLatent()) |
|
621 line->MakeVisible(EFalse); |
|
622 |
|
623 else if ( IsForm() ) |
|
624 line->ActivateL() ; |
|
625 } |
|
626 AknsUtils::RegisterControlPosition( this ) ; |
|
627 TInt count = iLines->Count(); |
|
628 for (TInt i = 0; i<count; i++) |
|
629 { |
|
630 CEikCaptionedControl *capCtrl = (*iLines)[i]; |
|
631 AknsUtils::RegisterControlPosition(capCtrl); |
|
632 AknsUtils::RegisterControlPosition(capCtrl->iCaption); |
|
633 AknsUtils::RegisterControlPosition(capCtrl->iControl); |
|
634 AknsUtils::RegisterControlPosition(capCtrl->iTrailer); |
|
635 AknsUtils::RegisterControlPosition(capCtrl->iBitmap); |
|
636 |
|
637 if ( capCtrl->iIsFormControl && iCurrentLine != i) |
|
638 { |
|
639 |
|
640 if (capCtrl->ControlIsAnEdwin(capCtrl->iControlType)) |
|
641 { |
|
642 CEikEdwin *edwin = (CEikEdwin*)capCtrl->iControl; |
|
643 TRAP_IGNORE(edwin->TextView()->SetDocPosL(0) |
|
644 ); |
|
645 } |
|
646 } |
|
647 |
|
648 } |
|
649 } |
|
650 |
|
651 void CEikDialogPage::SetActiveAndFocusL() |
|
652 { |
|
653 SetActiveL(); |
|
654 SetEditableL(iIsEditable, ETrue); |
|
655 //When active a page, need to show the focus in that page. |
|
656 ShowFocus( ETrue, EFalse ) ; |
|
657 // Display the focus on the current line |
|
658 if ( iCurrentLine == -1 || IsForm() ) |
|
659 { |
|
660 SetInitialFocus() ; |
|
661 } |
|
662 |
|
663 ExposeLine( iCurrentLine, EFalse ); |
|
664 UpdateScrollBarL(); |
|
665 } |
|
666 |
|
667 void CEikDialogPage::SetInactiveL() |
|
668 { |
|
669 MakeEdwinScrollbarsVisibleL(EFalse); |
|
670 MakeVisible(EFalse); |
|
671 } |
|
672 |
|
673 void CEikDialogPage::MakeEdwinScrollbarsVisibleL(TBool aVisible) |
|
674 { |
|
675 const TInt numLines=iLines->Count(); |
|
676 for (TInt ii=0;ii<numLines;ii++) |
|
677 { |
|
678 CEikCaptionedControl* thisLine=(*iLines)[ii]; |
|
679 const TInt controlType(thisLine->iControlType); |
|
680 if (thisLine->ControlIsAnEdwin(controlType)) |
|
681 { |
|
682 CEikEdwin* edwin=(CEikEdwin*)thisLine->iControl; |
|
683 if(edwin->Text()) |
|
684 edwin->ForceScrollBarUpdateL(); |
|
685 CEikScrollBarFrame* frame=edwin->ScrollBarFrame(); |
|
686 if (frame) |
|
687 { |
|
688 TInt count=frame->CountComponentControls(); |
|
689 for (TInt jj=0;jj<count;jj++) |
|
690 frame->ComponentControl(jj)->MakeVisible(aVisible); |
|
691 } |
|
692 } |
|
693 } |
|
694 } |
|
695 |
|
696 TInt CEikDialogPage::PageId() const |
|
697 { |
|
698 return iPageId; |
|
699 } |
|
700 |
|
701 TInt CEikDialogPage::LineId(const CCoeControl& aControl) const |
|
702 { |
|
703 TInt lineIndex=iLines->FindLineIndex(&aControl); |
|
704 if (lineIndex>=0) |
|
705 return (*iLines)[lineIndex]->iId; |
|
706 |
|
707 return KErrNotFound; |
|
708 } |
|
709 |
|
710 TBool CEikDialogPage::SetInitialFocus() |
|
711 { |
|
712 TBool focusSet=EFalse; |
|
713 |
|
714 const TInt numLines=iLines->Count(); |
|
715 for (TInt ii=0;ii<numLines;ii++) |
|
716 { |
|
717 CEikCaptionedControl* line=(*iLines)[ii]; |
|
718 if (line->IsNonFocusing() || line->IsDimmed() || !(line->IsVisible())) |
|
719 continue; |
|
720 ChangeFocusTo(ii); |
|
721 focusSet=ETrue; |
|
722 |
|
723 if ( IsForm() ) |
|
724 { |
|
725 // move line with initial focus to the screen |
|
726 iLines->MoveLineToScreen( ii, iPhysics->ViewTopY(), ETrue ); |
|
727 } |
|
728 break; |
|
729 } |
|
730 iExtension->iSetInitialFocusDone = ETrue; |
|
731 return focusSet; |
|
732 } |
|
733 |
|
734 TKeyResponse CEikDialogPage::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
735 { |
|
736 TKeyResponse response=EKeyWasNotConsumed; |
|
737 |
|
738 if (!(PageContainer()->PageSelector()->Dialg()->DialogFlags() & EEikDialogFlagDontEatUpDownEvents)) |
|
739 { |
|
740 if (aType != EEventKey) |
|
741 return response; |
|
742 } |
|
743 |
|
744 const TInt numLines=iLines->Count(); |
|
745 if ((iCurrentLine>-1)&&(iCurrentLine<numLines)) |
|
746 { |
|
747 // If the control changes size as a result of offering it the key event then it will be |
|
748 // necessary to reformat the page |
|
749 if ((aKeyEvent.iCode != EKeyTab && aKeyEvent.iCode != EKeyPrevious && aKeyEvent.iCode != EKeyNext) || (*iLines)[iCurrentLine]->ControlIsAPopfield((*iLines)[iCurrentLine]->iControlType) ) // tab keys are not offered to child controls |
|
750 { |
|
751 response=(*iLines)[iCurrentLine]->OfferKeyEventL(aKeyEvent,aType); |
|
752 } |
|
753 iExtension->iFocusedClicked = EFalse; |
|
754 } |
|
755 if (aType == EEventKey && response==EKeyWasConsumed) |
|
756 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
757 else if (aType == EEventKey && ( |
|
758 aKeyEvent.iCode==EKeyUpArrow |
|
759 || aKeyEvent.iCode==EKeyDownArrow |
|
760 || aKeyEvent.iCode==EKeyTab |
|
761 || aKeyEvent.iCode==EKeyNext |
|
762 || aKeyEvent.iCode==EKeyPrevious |
|
763 )) |
|
764 response=OfferUpDownKeyEventL(aKeyEvent,aType,ENonCyclic); |
|
765 return response; |
|
766 } |
|
767 |
|
768 TKeyResponse CEikDialogPage::OfferUpDownKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType,TFocusNavigationMode aFocusNavigationMode) |
|
769 { |
|
770 TKeyResponse response=EKeyWasNotConsumed; |
|
771 if (aType==EEventKey) |
|
772 { |
|
773 const TInt numLines=iLines->Count(); |
|
774 if ((iCurrentLine>-1)&&(iCurrentLine<numLines)) |
|
775 { |
|
776 if (!iFormControl || (*iLines)[iCurrentLine]->iIsEditable ) // non form controls should not have editable concept |
|
777 { |
|
778 // 1. Tab events are never forwarded. |
|
779 // 2. If it's a non-form dialog, then it is forwarded. |
|
780 // 3. If it's a form dialog, then it is forwarded if it's not |
|
781 // next/previous nor line is a popup field. |
|
782 if ( aKeyEvent.iCode != EKeyTab && |
|
783 ( !iFormControl || |
|
784 ( aKeyEvent.iCode != EKeyPrevious && aKeyEvent.iCode != EKeyNext ) || |
|
785 ( *iLines)[iCurrentLine]->ControlIsAPopfield((*iLines)[iCurrentLine]->iControlType ) ) ) |
|
786 { |
|
787 response=(*iLines)[iCurrentLine]->OfferKeyEventL(aKeyEvent,aType); |
|
788 } |
|
789 } |
|
790 else |
|
791 response=EKeyWasNotConsumed ; |
|
792 } |
|
793 if (response!=EKeyWasConsumed && |
|
794 (aKeyEvent.iCode==EKeyUpArrow |
|
795 || aKeyEvent.iCode==EKeyDownArrow |
|
796 || aKeyEvent.iCode==EKeyTab |
|
797 || aKeyEvent.iCode==EKeyNext |
|
798 || aKeyEvent.iCode==EKeyPrevious |
|
799 )) |
|
800 { |
|
801 iExtension->iFocusedClicked = ETrue; |
|
802 |
|
803 switch (aFocusNavigationMode) |
|
804 { |
|
805 case ECyclic: |
|
806 iExtension->iScrolled = ETrue; |
|
807 response=HandleCyclicFocusNavigationKeyL(aKeyEvent); |
|
808 break; |
|
809 |
|
810 case ENonCyclic: |
|
811 iExtension->iScrolled = ETrue; |
|
812 response=HandleNonCyclicFocusNavigationKeyL(aKeyEvent); |
|
813 break; |
|
814 |
|
815 default: |
|
816 break; |
|
817 }; |
|
818 |
|
819 if (response==EKeyWasConsumed) |
|
820 ReportEventL(MCoeControlObserver::EEventStateChanged); |
|
821 } |
|
822 } |
|
823 |
|
824 if (response==EKeyWasConsumed) |
|
825 UpdateScrollBarThumb(); |
|
826 |
|
827 return response; |
|
828 } |
|
829 |
|
830 TKeyResponse CEikDialogPage::HandleNonCyclicFocusNavigationKeyL(const TKeyEvent& aKeyEvent) |
|
831 { |
|
832 TKeyResponse response=EKeyWasNotConsumed; |
|
833 TBool up = EFalse; |
|
834 TBool down = EFalse; |
|
835 TBool tab = EFalse; |
|
836 TInt naviCount = 1; |
|
837 switch (aKeyEvent.iCode) |
|
838 { |
|
839 case EKeyPrevious: |
|
840 naviCount = aKeyEvent.iRepeats + 1; |
|
841 case EKeyUpArrow: |
|
842 up = ETrue; |
|
843 break; |
|
844 case EKeyNext: |
|
845 naviCount = aKeyEvent.iRepeats + 1; |
|
846 case EKeyDownArrow: |
|
847 down = ETrue; |
|
848 break; |
|
849 case EKeyTab: |
|
850 tab = ETrue; |
|
851 if (aKeyEvent.iModifiers & EModifierShift) |
|
852 { |
|
853 up = ETrue; |
|
854 } |
|
855 else |
|
856 { |
|
857 down = ETrue; |
|
858 } |
|
859 break; |
|
860 default: |
|
861 ASSERT(EFalse); |
|
862 }; |
|
863 |
|
864 if (up) |
|
865 { |
|
866 if (iCurrentLine!=TopFocusableLine()||(iExtension->iIsDoubleQuery&&tab)) |
|
867 { |
|
868 if (RotateFocusByL(-1*naviCount)) |
|
869 response=EKeyWasConsumed; |
|
870 } |
|
871 } |
|
872 if (down) |
|
873 { |
|
874 if (iCurrentLine!=BottomFocusableLine()||(iExtension->iIsDoubleQuery&&tab)) |
|
875 { |
|
876 if (RotateFocusByL(+1*naviCount)) |
|
877 response=EKeyWasConsumed; |
|
878 } |
|
879 else if (aKeyEvent.iRepeats>0) |
|
880 { |
|
881 response=EKeyWasConsumed; |
|
882 } |
|
883 |
|
884 } |
|
885 |
|
886 return response; |
|
887 } |
|
888 |
|
889 TKeyResponse CEikDialogPage::HandleCyclicFocusNavigationKeyL(const TKeyEvent& aKeyEvent) |
|
890 { |
|
891 TKeyResponse response=EKeyWasNotConsumed; |
|
892 |
|
893 switch (aKeyEvent.iCode) |
|
894 { |
|
895 case EKeyUpArrow: |
|
896 if (!(iCurrentLine==TopFocusableLine() && aKeyEvent.iRepeats>0)) // Check not reached top from a repeated key event. |
|
897 { |
|
898 if (RotateFocusByL(-1)) |
|
899 response=EKeyWasConsumed; |
|
900 } |
|
901 break; |
|
902 case EKeyDownArrow: |
|
903 if (!(iCurrentLine==BottomFocusableLine() && aKeyEvent.iRepeats>0)) // Check not reached bottom from a repeated key event. |
|
904 { |
|
905 if (RotateFocusByL(+1)) |
|
906 response=EKeyWasConsumed; |
|
907 } |
|
908 break; |
|
909 default: |
|
910 ASSERT(EFalse); |
|
911 } |
|
912 |
|
913 return response; |
|
914 } |
|
915 |
|
916 TBool CEikDialogPage::OwnsLine(TInt aLineId) const |
|
917 { |
|
918 TBool ownsLine=EFalse; |
|
919 |
|
920 const TInt numLines=iLines->Count(); |
|
921 for (TInt ii=0;ii<numLines;ii++) |
|
922 { |
|
923 if ((*iLines)[ii]->iId==aLineId) |
|
924 { |
|
925 ownsLine=ETrue; |
|
926 break; |
|
927 } |
|
928 } |
|
929 |
|
930 return ownsLine; |
|
931 } |
|
932 |
|
933 void CEikDialogPage::SetDimmed(TBool aDimmed) |
|
934 { |
|
935 CCoeControl::SetDimmed(aDimmed); |
|
936 |
|
937 const TInt numLines=iLines->Count(); |
|
938 for (TInt ii=0;ii<numLines;ii++) |
|
939 { |
|
940 CEikCaptionedControl* thisLine=(*iLines)[ii]; |
|
941 thisLine->iControl->SetDimmed(aDimmed); |
|
942 thisLine->CheckDimmedDisplayState(); |
|
943 } |
|
944 } |
|
945 |
|
946 TBool CEikDialogPage::RotateFocusByL(TInt aDelta) |
|
947 { |
|
948 TInt numLines=iLines->Count(); |
|
949 if (numLines == 0) |
|
950 return(EFalse); |
|
951 |
|
952 // If form is in view mode and highlight is hidden then the first |
|
953 // navigation key press just displays the highlight. |
|
954 if ( IsForm() && !IsEditable() && !HighlightVisible() ) |
|
955 { |
|
956 HighlightVisible( ETrue ); |
|
957 |
|
958 TInt lineIndex = iLines->FocusableLine( iCurrentLine, |
|
959 iPhysics->ViewTopY() ); |
|
960 |
|
961 if ( lineIndex != KErrNotFound ) |
|
962 { |
|
963 if ( lineIndex == iCurrentLine ) |
|
964 { |
|
965 CEikCaptionedControl* line = (*iLines)[iCurrentLine]; |
|
966 ShowFocus( ETrue, ETrue ); |
|
967 } |
|
968 else |
|
969 { |
|
970 iExtension->iLastTouchedLine = lineIndex; |
|
971 HandleHighlightTimer(); |
|
972 } |
|
973 } |
|
974 |
|
975 return ETrue; |
|
976 } |
|
977 |
|
978 TInt max=numLines-1; |
|
979 TInt currentLine=iCurrentLine; |
|
980 while (numLines--) |
|
981 { |
|
982 currentLine+=aDelta; |
|
983 |
|
984 |
|
985 if (currentLine<0) |
|
986 currentLine=0; |
|
987 else if (currentLine>max) |
|
988 currentLine=max; |
|
989 |
|
990 (*iLines)[currentLine]->ActivateL() ; // ensure that the current line is activated. |
|
991 |
|
992 if (!(LineIsFocusable(currentLine))) |
|
993 continue; |
|
994 |
|
995 PrepareForFocusTransitionL(); |
|
996 |
|
997 if (!(LineIsFocusable(currentLine))) |
|
998 continue; |
|
999 |
|
1000 ChangeFocusToAndExposeL(currentLine); |
|
1001 LineChangedL((*iLines)[currentLine]->iId); |
|
1002 iExtension->iFocusedClicked = ETrue; |
|
1003 return(ETrue); |
|
1004 } |
|
1005 |
|
1006 return EFalse; |
|
1007 } |
|
1008 |
|
1009 void CEikDialogPage::ChangeFocusToAndExposeL( TInt aLine, TBool /*aShowWholeControl*/ ) |
|
1010 { |
|
1011 if ( aLine < 0 || aLine == iCurrentLine ) |
|
1012 return; |
|
1013 |
|
1014 TInt oldLine = iCurrentLine; |
|
1015 |
|
1016 if( aLine != iCurrentLine ) |
|
1017 (*iLines)[iCurrentLine]->ScrollBackEditor(); |
|
1018 |
|
1019 ChangeFocusTo( aLine ); |
|
1020 ExposeLine( iCurrentLine, EFalse ); |
|
1021 |
|
1022 if ( oldLine != iCurrentLine ) |
|
1023 { |
|
1024 |
|
1025 // If secret editor, cursor position should be update again to reflect |
|
1026 // screen scroll caused by ExposeLine(...) |
|
1027 CEikCaptionedControl* currentLine=(*iLines)[iCurrentLine]; |
|
1028 if( IsForm() && currentLine->ControlIsASecretEditor(currentLine->iControlType) ) |
|
1029 { |
|
1030 ShowFocus(ETrue, EFalse); |
|
1031 } |
|
1032 |
|
1033 DrawDeferred(); |
|
1034 } |
|
1035 } |
|
1036 |
|
1037 TInt CEikDialogPage::TopFocusableLine() const |
|
1038 { |
|
1039 const TInt numLines=iLines->Count(); |
|
1040 for (TInt i=0;i<numLines;i++) |
|
1041 { |
|
1042 if (LineIsFocusable(i)) |
|
1043 return i; |
|
1044 } |
|
1045 |
|
1046 return KErrNotFound; |
|
1047 } |
|
1048 |
|
1049 TInt CEikDialogPage::BottomFocusableLine() const |
|
1050 { |
|
1051 const TInt numLines=iLines->Count(); |
|
1052 for (TInt i=numLines-1;i>=0;i--) |
|
1053 { |
|
1054 if (LineIsFocusable(i)) |
|
1055 return i; |
|
1056 } |
|
1057 |
|
1058 return KErrNotFound; |
|
1059 } |
|
1060 |
|
1061 TBool CEikDialogPage::LineIsFocusable(TInt aLine) const |
|
1062 { |
|
1063 TBool focusable(ETrue); |
|
1064 CEikCaptionedControl* line=(*iLines)[aLine]; |
|
1065 |
|
1066 if (line->IsNonFocusing() || line->IsDimmed() || !(line->IsVisible())) |
|
1067 focusable=EFalse; |
|
1068 |
|
1069 return focusable; |
|
1070 } |
|
1071 |
|
1072 void CEikDialogPage::SetDensePacking(TBool aDensePacking) |
|
1073 { |
|
1074 iLines->SetDensePacking(aDensePacking); |
|
1075 } |
|
1076 |
|
1077 void CEikDialogPage::InsertLineL(TInt aPosition,TInt aResourceId) |
|
1078 { |
|
1079 // alteration is bloated but should not provide any side-effects. |
|
1080 if (!iFormControl) |
|
1081 { |
|
1082 CEikCaptionedControl* line=ConstructLineL(aResourceId); |
|
1083 CleanupStack::PushL(line); |
|
1084 iLines->InsertL(aPosition,line); |
|
1085 CleanupStack::Pop(); // line |
|
1086 line->RegisterPageWithCaptionControl(this); |
|
1087 return; |
|
1088 } |
|
1089 ShowFocus( EFalse,EFalse ) ; |
|
1090 CEikCaptionedControl* line=ConstructLineL(aResourceId); |
|
1091 CleanupStack::PushL(line); |
|
1092 line->SetComponentsToInheritVisibility(); |
|
1093 iLines->InsertL(aPosition,line); |
|
1094 CleanupStack::Pop(); // line now owned by iLines. |
|
1095 AfterAddingNewLinesL(aPosition); |
|
1096 /* |
|
1097 iCurrentLine should be increased as it is relative to the lines in that page |
|
1098 and we have just added a new line before it in the page. |
|
1099 */ |
|
1100 if (iCurrentLine>=aPosition) |
|
1101 iCurrentLine++; |
|
1102 } |
|
1103 |
|
1104 void CEikDialogPage::DeleteLine(TInt aLineId, TBool aRedraw) |
|
1105 { |
|
1106 TInt index( LineIndex( aLineId ) ) ; |
|
1107 if ( index == iCurrentLine ) // we're deleting the current line |
|
1108 { |
|
1109 // If this is the last line then move the focus to the line above. (becomes -1 if last line) |
|
1110 if( iCurrentLine == iLines->Count() - 1 ) |
|
1111 iCurrentLine-- ; |
|
1112 /* |
|
1113 LastExposedLine is needed for when to remember control positions in forms. |
|
1114 If we've deleted that line, forget it. |
|
1115 */ iLastExposedLine=-1; |
|
1116 } |
|
1117 else |
|
1118 { |
|
1119 /* Since iCurrentLine is relative to the positions in the form, if we've deleted a line which |
|
1120 comes before it in the list, we should reduce iCurrentLine by 1. |
|
1121 Same is true for LastExposedLine. |
|
1122 */ |
|
1123 if (index<iCurrentLine) |
|
1124 { |
|
1125 iCurrentLine--; |
|
1126 iLastExposedLine--; |
|
1127 } |
|
1128 } |
|
1129 // Actually delete the line. |
|
1130 TInt lineIndex = LineIndex( aLineId ); |
|
1131 |
|
1132 // delete line's cached draw commands |
|
1133 if ( IsForm() ) |
|
1134 { |
|
1135 iExtension->iRecordingGc->DeleteLine( lineIndex ); |
|
1136 } |
|
1137 |
|
1138 iLines->DeleteLine( lineIndex ); |
|
1139 |
|
1140 ReconsiderPageSize(); |
|
1141 |
|
1142 if (aRedraw) |
|
1143 { |
|
1144 if (iCurrentLine!=-1) |
|
1145 { |
|
1146 TInt targetLine = iCurrentLine ; |
|
1147 iCurrentLine = -1 ; |
|
1148 ChangeFocusTo( targetLine ) ; |
|
1149 ExposeLine( targetLine, ETrue ) ; |
|
1150 ShowFocus( ETrue, EFalse ) ; |
|
1151 } |
|
1152 |
|
1153 DrawNow(); |
|
1154 TRAP_IGNORE(UpdateScrollBarL()); // if OOM, scrollbar will not be updated - No great loss. |
|
1155 } |
|
1156 } |
|
1157 |
|
1158 void CEikDialogPage::AdjustAllIds(TInt aControlIdDelta) |
|
1159 { |
|
1160 iLines->AdjustAllIds(aControlIdDelta); |
|
1161 } |
|
1162 |
|
1163 TInt CEikDialogPage::FocusLineL(TInt aLineId) |
|
1164 { |
|
1165 TInt lineIndex=LineIndex(aLineId); |
|
1166 |
|
1167 if (lineIndex==KErrNotFound) |
|
1168 return KErrNotFound; |
|
1169 |
|
1170 PrepareForFocusTransitionL(); |
|
1171 // Show whole line, not scroll into line. |
|
1172 ChangeFocusToAndExposeL(lineIndex, ETrue); |
|
1173 LineChangedL(aLineId); |
|
1174 return KErrNone; |
|
1175 } |
|
1176 |
|
1177 TInt CEikDialogPage::FocusedLineId() const |
|
1178 { |
|
1179 if (iCurrentLine>=0) |
|
1180 return (*iLines)[iCurrentLine]->iId; |
|
1181 return 0; |
|
1182 } |
|
1183 |
|
1184 void CEikDialogPage::GetAutoValues() |
|
1185 { |
|
1186 const TInt numLines=iLines->Count(); |
|
1187 for (TInt ii=0;ii<numLines;ii++) |
|
1188 { |
|
1189 CEikCaptionedControl* line=(*iLines)[ii]; |
|
1190 TAny* returnValue=line->iReturnValue; |
|
1191 if (!returnValue) |
|
1192 continue; |
|
1193 CCoeControl* control=line->iControl; |
|
1194 switch (line->iControlType) |
|
1195 { |
|
1196 case EEikCtEdwin: |
|
1197 ((CEikEdwin*)control)->GetText(*(TDes*)returnValue); |
|
1198 break; |
|
1199 case EEikCtSecretEd: |
|
1200 ((CEikSecretEditor*)control)->GetText(*(TDes*)returnValue); |
|
1201 break; |
|
1202 |
|
1203 case EEikCtFlPtEd: |
|
1204 (*(TReal*)returnValue)=((CEikFloatingPointEditor*)control)->Value(); |
|
1205 break; |
|
1206 case EEikCtFxPtEd: |
|
1207 (*(TInt*)returnValue)=((CEikFixedPointEditor*)control)->Value(); |
|
1208 break; |
|
1209 |
|
1210 case EEikCtNumberEditor: |
|
1211 (*(TInt*)returnValue)=((CEikNumberEditor*)control)->Number(); |
|
1212 break; |
|
1213 case EEikCtRangeEditor: |
|
1214 (*(SEikRange*)returnValue)=((CEikRangeEditor*)control)->Range(); |
|
1215 break; |
|
1216 case EEikCtTimeEditor: |
|
1217 (*(TTime*)returnValue)=((CEikTimeEditor*)control)->Time(); |
|
1218 break; |
|
1219 case EEikCtDateEditor: |
|
1220 (*(TTime*)returnValue)=((CEikDateEditor*)control)->Date(); |
|
1221 break; |
|
1222 case EEikCtTimeAndDateEditor: |
|
1223 (*(TTime*)returnValue)=((CEikTimeAndDateEditor*)control)->TimeAndDate(); |
|
1224 break; |
|
1225 case EEikCtDurationEditor: |
|
1226 (*(TTimeIntervalSeconds*)returnValue)=((CEikDurationEditor*)control)->Duration(); |
|
1227 break; |
|
1228 case EEikCtTimeOffsetEditor: |
|
1229 (*(TTimeIntervalSeconds*)returnValue)=((CEikTimeOffsetEditor*)control)->TimeOffset(); |
|
1230 break; |
|
1231 |
|
1232 default: |
|
1233 ASSERT(iPageObserver); |
|
1234 iPageObserver->GetCustomAutoValue(returnValue,line->iControlType,control); |
|
1235 break; |
|
1236 } |
|
1237 } |
|
1238 } |
|
1239 |
|
1240 TInt CEikDialogPage::LineIndex(TInt aLineId) |
|
1241 { |
|
1242 const TInt numLines=iLines->Count(); |
|
1243 for (TInt ii=0;ii<numLines;ii++) |
|
1244 { |
|
1245 if ((*iLines)[ii]->iId==aLineId) |
|
1246 return ii; |
|
1247 } |
|
1248 |
|
1249 return KErrNotFound; |
|
1250 } |
|
1251 |
|
1252 TInt CEikDialogPage::YPosToLine2(TInt aYPos) const |
|
1253 { |
|
1254 return iLines->YPosToLine( Rect(), iScroll->Top(), iScroll->Middle(), iScroll->Bottom(), aYPos ); |
|
1255 } |
|
1256 |
|
1257 TInt CEikDialogPage::LineToYPos(TInt& aLine) const |
|
1258 // |
|
1259 // Calcs YPos of line relative to the ViewWin and adjusts aLine if its out of bounds |
|
1260 { |
|
1261 ASSERT(iLines); |
|
1262 const TInt numLines=iLines->Count(); |
|
1263 ASSERT(numLines>0); |
|
1264 if (aLine<0) |
|
1265 aLine=0; |
|
1266 else if (aLine>=numLines) |
|
1267 aLine=numLines-1; |
|
1268 return (*iLines)[aLine]->Position().iY; // TPREMOVAL +iDataWinPos.iY; |
|
1269 } |
|
1270 |
|
1271 void CEikDialogPage::ExposeLine(TInt aLine, TBool aForceResize, TBool aShowWholeLine) |
|
1272 // |
|
1273 /* Exposes the given line so that its fully visible in the ViewWin |
|
1274 */ { |
|
1275 if ( iSize.iHeight == 0 || aLine == -1 ) |
|
1276 { |
|
1277 return; |
|
1278 } |
|
1279 |
|
1280 CAknPaneScroll::TScrollChangeType change = iScroll->ExposeLine( aLine, aShowWholeLine ); |
|
1281 |
|
1282 if ( change == CAknPaneScroll::ENoChange && !aForceResize ) |
|
1283 { |
|
1284 return; |
|
1285 } |
|
1286 |
|
1287 CEikCaptionedControl* capCtrl = (*iLines)[aLine]; |
|
1288 capCtrl->MinimumSize(); |
|
1289 TInt controlHeight (ControlHeight( aLine )); |
|
1290 TInt focusedControlsPositionInDataWin (capCtrl->Position().iY); |
|
1291 |
|
1292 if ( IsForm() ) |
|
1293 { |
|
1294 focusedControlsPositionInDataWin = iLines->LineIndexToYPosition( aLine, 0 ); |
|
1295 } |
|
1296 |
|
1297 TInt topYPosOfControlWhichMustBeViewable = focusedControlsPositionInDataWin; |
|
1298 TInt bottomYPosOfControlWhichMustBeViewable = focusedControlsPositionInDataWin+controlHeight; |
|
1299 TInt controlType = capCtrl->iControlType; |
|
1300 |
|
1301 // make the default value for where we'd like the datawinpos offset to be the current value |
|
1302 TInt idealDataWindowPosition = 0; |
|
1303 /* |
|
1304 If it's not a form, the values set above should be fine |
|
1305 */ |
|
1306 if ( iFormControl && !aShowWholeLine ) |
|
1307 { |
|
1308 if ( aLine == iLastExposedLine && !capCtrl->ControlIsAnEdwin( controlType ) && iFormControl ) |
|
1309 { |
|
1310 /* |
|
1311 We want to position this control as near to the place it was before as possible |
|
1312 Important for growing and shrinking of popupfields. |
|
1313 Hence set the datawin as the remembered position |
|
1314 (the position is stored relative to the view win, hence the calculation) |
|
1315 */ |
|
1316 idealDataWindowPosition = (-1*topYPosOfControlWhichMustBeViewable)+iLastExposedLineViewWinYPosition; |
|
1317 |
|
1318 topYPosOfControlWhichMustBeViewable = iLastExposedLineViewWinYPosition; |
|
1319 bottomYPosOfControlWhichMustBeViewable = topYPosOfControlWhichMustBeViewable + controlHeight; |
|
1320 } |
|
1321 } |
|
1322 |
|
1323 SetDataPosition( topYPosOfControlWhichMustBeViewable, bottomYPosOfControlWhichMustBeViewable, aForceResize ); |
|
1324 |
|
1325 if ( aLine != iLastExposedLine ) |
|
1326 { |
|
1327 iLastExposedLine = aLine; |
|
1328 iLastExposedLineViewWinYPosition = topYPosOfControlWhichMustBeViewable + idealDataWindowPosition; |
|
1329 } |
|
1330 } |
|
1331 |
|
1332 void CEikDialogPage::SetDataPosition( TInt aTopY, TInt aBottomY, TBool aForceResize ) |
|
1333 { |
|
1334 // update rect only if the currently focused control doesn't fit |
|
1335 if ( iFormControl ) |
|
1336 { |
|
1337 TInt topY = iPhysics->ViewTopY(); |
|
1338 TInt maxBottomY = topY + iSize.iHeight; |
|
1339 |
|
1340 if ( aForceResize || aTopY < topY || aBottomY > maxBottomY ) |
|
1341 { |
|
1342 TInt totalHeight = 0; |
|
1343 TInt count = iLines->Count(); |
|
1344 TPoint viewCenter( iPhysics->ViewCenter() ); |
|
1345 |
|
1346 for ( TInt i = 0; i < count; ++i ) |
|
1347 { |
|
1348 totalHeight += (*iLines)[i]->Rect().Height(); |
|
1349 } |
|
1350 |
|
1351 if ( totalHeight > iSize.iHeight ) |
|
1352 { |
|
1353 if( aTopY < topY ) |
|
1354 { |
|
1355 viewCenter.iY = iPhysics->ViewCenter().iY - topY + aTopY; |
|
1356 } |
|
1357 else if( aBottomY > maxBottomY ) |
|
1358 { |
|
1359 viewCenter.iY = iPhysics->ViewCenter().iY + aBottomY - maxBottomY; |
|
1360 } |
|
1361 else if( totalHeight < ( iPhysics->ViewCenter().iY + iPhysics->ViewCenterDistance() ) ) |
|
1362 { |
|
1363 viewCenter.iY = totalHeight - iPhysics->ViewCenterDistance(); |
|
1364 } |
|
1365 else |
|
1366 { |
|
1367 viewCenter.iY = iPhysics->ViewCenter().iY; |
|
1368 } |
|
1369 } |
|
1370 else |
|
1371 { |
|
1372 viewCenter.iY = iPhysics->ViewCenterDistance(); |
|
1373 } |
|
1374 |
|
1375 iPhysics->SetViewCenter( viewCenter ); |
|
1376 iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue ); |
|
1377 } |
|
1378 } |
|
1379 } |
|
1380 |
|
1381 /* |
|
1382 class CDummy: public CCoeControl |
|
1383 { |
|
1384 public: |
|
1385 TBool IsReadyToDraw() const |
|
1386 { |
|
1387 return CCoeControl::IsReadyToDraw(); |
|
1388 } |
|
1389 }; |
|
1390 |
|
1391 if ( iPhysics ) |
|
1392 { |
|
1393 // Awful hack below is used to prevent some unwanted drawing that would |
|
1394 // otherwise occur during form's initialization. |
|
1395 // |
|
1396 // Unfortunately CCoeControl::IsActivated is protected so we need to |
|
1397 // work around that somehow... |
|
1398 CCoeControl* parent = WindowOwningParent(); |
|
1399 |
|
1400 if ( parent ) |
|
1401 { |
|
1402 CDummy* fakeParent = reinterpret_cast<CDummy*>( parent ); |
|
1403 TBool isReadyToDraw = fakeParent->IsReadyToDraw(); |
|
1404 |
|
1405 if ( isReadyToDraw ) |
|
1406 { |
|
1407 DrawNow(); |
|
1408 } |
|
1409 } |
|
1410 } |
|
1411 */ |
|
1412 |
|
1413 TInt CEikDialogPage::ControlHeight(TInt aLineIndex) const |
|
1414 { |
|
1415 return (*iLines)[aLineIndex]->Size().iHeight; |
|
1416 } |
|
1417 |
|
1418 void CEikDialogPage::SizeChanged() |
|
1419 { |
|
1420 // update form area's size to scroll control |
|
1421 iScroll->SetOutsideRect( Rect() ); |
|
1422 iLines->SetRect( Rect(), iScroll->Top(), iScroll->Middle(), iScroll->Bottom() ); |
|
1423 |
|
1424 if ( (iLines->Count() > 0 ) && ( iCurrentLine >= 0 ) ) |
|
1425 { |
|
1426 ExposeLine( iCurrentLine, EFalse ); |
|
1427 } |
|
1428 |
|
1429 TRAP_IGNORE( UpdateScrollBarL() ); // ignore any errors. |
|
1430 AknsUtils::RegisterControlPosition( this ); |
|
1431 |
|
1432 UpdatePhysics(); |
|
1433 iExtension->iInitialLayoutDone = ETrue; |
|
1434 } |
|
1435 |
|
1436 TSize CEikDialogPage::MinimumSize() |
|
1437 { |
|
1438 return TSize( iLines->MinimumSize().iWidth, 0 ); // Can be zero height |
|
1439 } |
|
1440 |
|
1441 void CEikDialogPage::PrepareForFocusLossL() |
|
1442 { |
|
1443 PrepareForFocusTransitionL(); |
|
1444 } |
|
1445 |
|
1446 /** |
|
1447 * Writes the internal state of the control and its components to aStream. |
|
1448 * Does nothing in release mode. |
|
1449 * Designed to be overidden and base called by subclasses. |
|
1450 * |
|
1451 * @internal |
|
1452 * @since App-Framework_6.1 |
|
1453 */ |
|
1454 #ifndef _DEBUG |
|
1455 void CEikDialogPage::WriteInternalStateL(RWriteStream&) const |
|
1456 {} |
|
1457 #else |
|
1458 void CEikDialogPage::WriteInternalStateL(RWriteStream& aWriteStream) const |
|
1459 { |
|
1460 CCoeControl::WriteInternalStateL(aWriteStream); |
|
1461 } |
|
1462 #endif |
|
1463 |
|
1464 TSize CEikDialogPage::PreferredSize() const |
|
1465 { |
|
1466 return CONST_CAST(CEikDialogPage*,this)->iLines->MinimumSize(); |
|
1467 } |
|
1468 |
|
1469 TBool CEikDialogPage::HandleEdwinSizeEventL(CEikEdwin* aEdwin, TEdwinSizeEvent aEventType, TSize aDesirableEdwinSize) |
|
1470 { |
|
1471 switch (aEventType) |
|
1472 { |
|
1473 case EEventSizeChanging: |
|
1474 |
|
1475 if ( iFormFlags & EFormResizeOptimisationFlag ) // Flag indicates that resizing is not necessary now (it will be done later) |
|
1476 return EFalse ; |
|
1477 if (iCurrentLine>=0&& iIgnoreFurtherEdwinResizeEvents!=aEdwin) |
|
1478 return ResizeEdwinToFitTextL(aEdwin, EDrawNow, aDesirableEdwinSize); |
|
1479 break; |
|
1480 default: |
|
1481 break; |
|
1482 } |
|
1483 return EFalse; |
|
1484 } |
|
1485 |
|
1486 /** |
|
1487 * From MEikEdwinObserver. Look for navigation and editor text update events, as scrolling |
|
1488 might be required to keep cursor visible. |
|
1489 */ |
|
1490 void CEikDialogPage::HandleEdwinEventL(CEikEdwin* aEdwin,TEdwinEvent aEventType) |
|
1491 { |
|
1492 if ( IsForm() && ( aEventType == EEventTextUpdate |
|
1493 || aEventType == EEventTextUpdateAPI ) ) |
|
1494 { |
|
1495 CEikCaptionedControl* line = NULL; |
|
1496 TInt controlType = -1; |
|
1497 |
|
1498 for ( TInt i = 0; i < iLines->Count(); ++i ) |
|
1499 { |
|
1500 line = (*iLines)[i]; |
|
1501 controlType = line->ControlType(); |
|
1502 |
|
1503 if ( line->ControlIsAnEdwin( controlType ) ) |
|
1504 { |
|
1505 if ( line->iControl == aEdwin ) |
|
1506 { |
|
1507 RecordLineL( i ); |
|
1508 |
|
1509 if ( i != iCurrentLine ) |
|
1510 { |
|
1511 DrawNow(); |
|
1512 } |
|
1513 |
|
1514 break; |
|
1515 } |
|
1516 } |
|
1517 } |
|
1518 } |
|
1519 |
|
1520 if( iCurrentLine == iLastExposedLine || iCurrentLine == -1 ) |
|
1521 return; |
|
1522 if( aEventType == EEventNavigation || aEventType == EEventTextUpdate ) |
|
1523 { |
|
1524 ExposeLine( iCurrentLine, EFalse ); |
|
1525 |
|
1526 UpdateScrollBarL(); |
|
1527 } |
|
1528 } |
|
1529 |
|
1530 /** |
|
1531 * Handle events caused by popup field controls, and resize if necessary |
|
1532 */ |
|
1533 void CEikDialogPage::HandlePopupFieldEventL(CAknPopupField* aPopupField, TAknPopupFieldEvent aEventType, TInt /*aHint*/) |
|
1534 { |
|
1535 switch (aEventType) |
|
1536 { |
|
1537 case EAknPopupFieldEventValueChange: |
|
1538 { |
|
1539 CEikCaptionedControl* line = NULL; |
|
1540 for ( TInt i = 0; i < iLines->Count(); ++i ) |
|
1541 { |
|
1542 line = (*iLines)[i]; |
|
1543 if ( line->iControl == aPopupField ) |
|
1544 { |
|
1545 if ( IsForm() ) |
|
1546 { |
|
1547 RecordLineL( i ); |
|
1548 } |
|
1549 DrawNow(); |
|
1550 break; |
|
1551 } |
|
1552 } |
|
1553 break; |
|
1554 } |
|
1555 case EAknPopupFieldEventModeChange: |
|
1556 { |
|
1557 TInt index = iCurrentLine; |
|
1558 |
|
1559 if(iIsEditable && (iExtension->iPopFieldEvents != 0)) |
|
1560 { |
|
1561 iExtension->iPopFieldEvents = 0; |
|
1562 SetScbState(EFalse); |
|
1563 } |
|
1564 else |
|
1565 { |
|
1566 iExtension->iPopFieldEvents = 1; |
|
1567 } |
|
1568 |
|
1569 ReconsiderPageSize(); |
|
1570 ExposeLine( index, ETrue ); |
|
1571 DrawNow(); |
|
1572 |
|
1573 UpdateScrollBarL(); |
|
1574 PrepareToDrawVerticalLine(); |
|
1575 break; |
|
1576 } |
|
1577 default: |
|
1578 break; |
|
1579 } |
|
1580 } |
|
1581 |
|
1582 void CEikDialogPage::PrepareToDrawVerticalLine() const |
|
1583 { // to avoid flushes, we resize skin frame bitmaps before actual draw. |
|
1584 // NOTE, this should be possiblie to call from SizeChanged() or OfferKeyEventL() method :-) (the GC?) |
|
1585 |
|
1586 if (AknsUtils::AvkonSkinEnabled()) |
|
1587 { |
|
1588 MAknsSkinInstance* skin = AknsUtils::SkinInstance() ; |
|
1589 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ) ; |
|
1590 if ( CurrentLine() ) |
|
1591 { |
|
1592 TRect rectNotToDrawOuter( CurrentLine()->Rect() ) ; |
|
1593 TRect rectNotToDrawInner ; |
|
1594 |
|
1595 if ( iIsEditable ) |
|
1596 { |
|
1597 rectNotToDrawInner.iTl = EditFrameTopLeftRect( rectNotToDrawOuter ).iBr ; |
|
1598 rectNotToDrawInner.iBr = EditFrameBottomRightRect( rectNotToDrawOuter ).iTl ; |
|
1599 AknsDrawUtils::PrepareFrame( skin, |
|
1600 rectNotToDrawOuter, |
|
1601 rectNotToDrawInner, |
|
1602 KAknsIIDQsnFrInput, |
|
1603 KAknsIIDDefault ) ; |
|
1604 } |
|
1605 |
|
1606 } |
|
1607 |
|
1608 } |
|
1609 |
|
1610 } |
|
1611 |
|
1612 void CEikDialogPage::DrawVerticalLine() const |
|
1613 { |
|
1614 } |
|
1615 |
|
1616 void CEikDialogPage::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType) |
|
1617 { |
|
1618 switch (aEventType) |
|
1619 { |
|
1620 case EEventPrepareFocusTransition: |
|
1621 PrepareForFocusTransitionL(); |
|
1622 break; |
|
1623 case EEventRequestFocus: |
|
1624 ChangeFocusTo(FindLineIndex(aControl)); |
|
1625 break; |
|
1626 case EEventStateChanged: |
|
1627 /* |
|
1628 if current line is at the top/bottom of the visible page |
|
1629 AND the page is in edit mode, |
|
1630 redraw the line in the captionedcontrol. |
|
1631 */ |
|
1632 if (iCurrentLine!=-1) |
|
1633 { |
|
1634 CEikCaptionedControl* line = (*iLines)[iCurrentLine]; |
|
1635 if (line->ControlIsAnEdwin(line->iControlType)) |
|
1636 { |
|
1637 if ( |
|
1638 (IsAtOrOffBottomOfPage(STATIC_CAST(CEikEdwin*,line->iControl))) || |
|
1639 (IsAtOrOffTopOfPage(STATIC_CAST(CEikEdwin*,line->iControl))) |
|
1640 ) |
|
1641 { |
|
1642 line->DrawClosingLine(); |
|
1643 } |
|
1644 } |
|
1645 } |
|
1646 |
|
1647 if ( IsForm() ) |
|
1648 { |
|
1649 CEikCaptionedControl* line = NULL; |
|
1650 for ( TInt i = 0; i < iLines->Count(); ++i ) |
|
1651 { |
|
1652 line = (*iLines)[i]; |
|
1653 if ( line->iControl == aControl ) |
|
1654 { |
|
1655 RecordLineL( i ); |
|
1656 break; |
|
1657 } |
|
1658 } |
|
1659 } |
|
1660 |
|
1661 PassOnEventL(aControl,aEventType); |
|
1662 break; |
|
1663 case EEventRequestExit: |
|
1664 case EEventRequestCancel: |
|
1665 case EEventInteractionRefused: |
|
1666 default: |
|
1667 break; |
|
1668 } |
|
1669 } |
|
1670 |
|
1671 void CEikDialogPage::PassOnEventL(CCoeControl* aControl,MCoeControlObserver::TCoeEvent aEvent) |
|
1672 { |
|
1673 MCoeControlObserver* observer=Observer(); |
|
1674 if (observer) |
|
1675 observer->HandleControlEventL(aControl,aEvent); |
|
1676 } |
|
1677 |
|
1678 TBool CEikDialogPage::ResizeEdwinToFitTextL(CEikEdwin* aEdwin, TDrawNow /*aDrawNow*/, TSize aDesirableEdwinSize) |
|
1679 // |
|
1680 { |
|
1681 TInt edwinYPosBefore = aEdwin->Position().iY; |
|
1682 TInt edwinHeightBefore = aEdwin->Size().iHeight; |
|
1683 |
|
1684 const TInt maxHeight=iSize.iHeight-(KSpaceFromTitle+KSpaceFromBottom); |
|
1685 TInt height = aDesirableEdwinSize.iHeight; |
|
1686 if (height > maxHeight) |
|
1687 height = maxHeight; |
|
1688 |
|
1689 TSize size = aEdwin->Size(); |
|
1690 TInt maximumEdwinHeight = aEdwin->MaximumHeight(); |
|
1691 // ensure maxheight as dynamic construction may be done whilst form is of zero height. |
|
1692 if ((maximumEdwinHeight > maxHeight) && maxHeight) |
|
1693 aEdwin->SetMaximumHeight(maxHeight); // Can't be bigger than form itself |
|
1694 else if ((maximumEdwinHeight == 0) && (size.iHeight == height)) |
|
1695 return EFalse; |
|
1696 |
|
1697 if ( (maximumEdwinHeight > 0) && (height > maximumEdwinHeight)) |
|
1698 height=maximumEdwinHeight; // Can't be bigger than edwin itself |
|
1699 size.iHeight = height; |
|
1700 |
|
1701 // Must force a size change on current captioned contrl even if control doesn't change size (so that edwin is resized by aknutils) |
|
1702 aEdwin->SetSize(size); |
|
1703 ReconsiderPageSize(); |
|
1704 ExposeLine(iCurrentLine, ETrue); |
|
1705 PrepareToDrawVerticalLine(); // do flushes here. |
|
1706 |
|
1707 /* improved redraw code |
|
1708 Due to some unpleasantness about dialogs, forms and requirements, to get caption controls |
|
1709 to draw properly requires a call to draw now. A system initiated draw does not work correctly |
|
1710 |
|
1711 Therefore the drawing code has been tailored to minimise redraws and improve behaviour, whilst |
|
1712 cleaning up the marks left behind from shrinking edwins, etc. |
|
1713 */ |
|
1714 TInt edwinYPosAfter = aEdwin->Position().iY; |
|
1715 TInt edwinHeightAfter = aEdwin->Size().iHeight; |
|
1716 |
|
1717 /* |
|
1718 if the control is at the bottom of the page it could have initiated scrolling |
|
1719 which requires a full redraw. |
|
1720 */ |
|
1721 DrawDeferred(); |
|
1722 if (edwinHeightBefore!=edwinHeightAfter) |
|
1723 { |
|
1724 /* |
|
1725 The scrollbar is updated here rather than in the more generic SizeChanged |
|
1726 as SizeChanged occurs multiple times on creation of multiline forms. |
|
1727 */ |
|
1728 TRAP_IGNORE(UpdateScrollBarL()); // ignore any errors |
|
1729 } |
|
1730 return ETrue; |
|
1731 } |
|
1732 |
|
1733 |
|
1734 static TInt CountNumberOfLines_Edwin(CEikEdwin *aEdwin, TRect aRect, TInt numOfLines) |
|
1735 { |
|
1736 TInt edwinLines = numOfLines; |
|
1737 TInt count = 0; |
|
1738 for(TInt i=0;i<edwinLines;i++) |
|
1739 { |
|
1740 TInt scrolledLines = aEdwin->TextLayout()->FirstLineInBand(); |
|
1741 TInt docPos = aEdwin->TextLayout()->FirstCharOnLine(scrolledLines + i+1); |
|
1742 TPoint point; |
|
1743 aEdwin->TextLayout()->PosInBand(docPos, point); |
|
1744 TInt yPos = point.iY; |
|
1745 TRect lineRect; |
|
1746 aEdwin->TextLayout()->GetLineRect(yPos, lineRect); |
|
1747 lineRect.iTl += aEdwin->Position(); |
|
1748 lineRect.iBr += aEdwin->Position(); |
|
1749 if (aRect.Contains(lineRect.iTl) && aRect.Contains(lineRect.iBr)) |
|
1750 count++; |
|
1751 } |
|
1752 return count; |
|
1753 } |
|
1754 static TInt CountNumberOfLines_Ctrl(CCoeControl *aControl, TRect aRect) |
|
1755 { |
|
1756 TRect rect = TRect(aControl->Position(), aControl->Size()); |
|
1757 TInt count = 0; |
|
1758 if (aRect.Contains(rect.iTl) && aRect.Contains(rect.iBr)) |
|
1759 count ++; |
|
1760 return count; |
|
1761 } |
|
1762 |
|
1763 static TInt CountNumberOfVisibleLines(CEikCaptionedControl *aControl, TRect aClipRect) |
|
1764 { |
|
1765 TInt count = 0; |
|
1766 if (aControl->ControlIsAnEdwin(aControl->iControlType)) |
|
1767 count += CountNumberOfLines_Edwin((CEikEdwin*)aControl->iControl, aClipRect, aControl->NumberOfLines()); |
|
1768 else |
|
1769 count += CountNumberOfLines_Ctrl(aControl->iControl, aClipRect); |
|
1770 count += CountNumberOfLines_Ctrl(aControl->iCaption, aClipRect); |
|
1771 return count; |
|
1772 } |
|
1773 |
|
1774 static TInt NumberOfTextLinesVisible(CEikCapCArray *aLines, TInt aItem, TRect aClipRect) |
|
1775 { |
|
1776 if (aItem < 0) return 0; |
|
1777 CEikCaptionedControl *control = (*aLines)[aItem]; |
|
1778 return CountNumberOfVisibleLines(control, aClipRect); |
|
1779 } |
|
1780 |
|
1781 |
|
1782 void CEikDialogPage::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType) |
|
1783 { |
|
1784 iExtension->iHandlingScrollEvent = ETrue; |
|
1785 |
|
1786 switch (aEventType) |
|
1787 { |
|
1788 case EEikScrollPageUp: |
|
1789 case EEikScrollPageDown: |
|
1790 case EEikScrollThumbDragVert: |
|
1791 iExtension->iScrolled = ETrue; |
|
1792 iExtension->iScrolling = ETrue; |
|
1793 iLines->MoveLineToScreen( iCurrentLine, 0, EFalse ); |
|
1794 break; |
|
1795 |
|
1796 default: |
|
1797 break; |
|
1798 } |
|
1799 |
|
1800 iPhysics->ViewPositionChanged( TPoint( iPhysics->ViewCenter().iX, |
|
1801 aScrollBar->ThumbPosition() + iPhysics->ViewCenterDistance() ), ETrue ); |
|
1802 |
|
1803 switch (aEventType) |
|
1804 { |
|
1805 case EEikScrollPageUp: |
|
1806 case EEikScrollPageDown: |
|
1807 case EEikScrollThumbReleaseVert: |
|
1808 iExtension->iScrolling = EFalse; |
|
1809 iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue ); |
|
1810 break; |
|
1811 |
|
1812 default: |
|
1813 break; |
|
1814 } |
|
1815 |
|
1816 iExtension->iHandlingScrollEvent = EFalse; |
|
1817 } |
|
1818 |
|
1819 TBool CEikDialogPage::LineHandlerCalled() const |
|
1820 { |
|
1821 return iExtension->iFlags.IsSet( CDialogPageExtension::ELineHandlerCalled ); |
|
1822 } |
|
1823 |
|
1824 TRect MainPane() |
|
1825 { |
|
1826 TRect mainPaneRect; |
|
1827 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect ); |
|
1828 return mainPaneRect; |
|
1829 } |
|
1830 |
|
1831 void CEikDialogPage::UpdateScrollBarL() |
|
1832 { |
|
1833 // Only forms in S60 need dialog's scrollbar. |
|
1834 if ( !iFormControl || !iPageContainer->ScrollBar() || iSize.iHeight == 0 || iSize.iWidth == 0 || iExtension->iHandlingScrollEvent ) |
|
1835 { |
|
1836 return; |
|
1837 } |
|
1838 |
|
1839 CAknScrollBar* scrollBar = STATIC_CAST(CAknScrollBar*, iPageContainer->ScrollBar()->VerticalScrollBar()); |
|
1840 |
|
1841 if (scrollBar) |
|
1842 { |
|
1843 TInt top = iScroll->Top(); |
|
1844 TInt middle = iScroll->Middle(); |
|
1845 TInt bottom = iScroll->Bottom(); |
|
1846 TRect parent( Rect() ); |
|
1847 TBool topmostPartial = top == -1; |
|
1848 iLines->CalcItemIndexes(top, middle, bottom, parent.Size()); |
|
1849 TInt extraLines = topmostPartial ? NumberOfTextLinesVisible(iLines, top-1, parent) : 0; |
|
1850 iExtension->iPreviousThumbPosition = iLines->NumberOfTextLinesBeforeLine( top - extraLines ); |
|
1851 |
|
1852 // Using form layout, since this is used by AknForm only |
|
1853 TAknWindowComponentLayout layout = TAknWindowComponentLayout::Compose( |
|
1854 AknLayoutScalable_Avkon::listscroll_form_pane(), |
|
1855 AknLayoutScalable_Avkon::scroll_pane_cp8()); |
|
1856 |
|
1857 TRect scrollBarParent( MainPane().Size()/*mainPaneRect.Size()*/ ); |
|
1858 |
|
1859 AknLayoutUtils::LayoutVerticalScrollBar(iPageContainer->ScrollBar(), scrollBarParent, layout.LayoutLine()); |
|
1860 if(!ScbState() && iCurrentLine!=-1 && iCurrentLine < iLines->Count() ) |
|
1861 { |
|
1862 CEikCaptionedControl *ctrl = (*iLines)[iCurrentLine]; |
|
1863 if(ctrl->ControlIsAPopfield(ctrl->iControlType)) |
|
1864 { |
|
1865 CAknPopupField::EAknPopupFieldSelectionMode mode = ((CAknPopupField*)ctrl->iControl)->SelectionMode(); |
|
1866 if (mode == CAknPopupField::EAknPopupFieldSelectionListMode) |
|
1867 { |
|
1868 return; |
|
1869 } |
|
1870 } |
|
1871 UpdateScrollBarThumb(); |
|
1872 } |
|
1873 } |
|
1874 } |
|
1875 |
|
1876 |
|
1877 void CEikDialogPage::UpdateScrollBarThumb() |
|
1878 { |
|
1879 if ( !iFormControl || !iPageContainer->ScrollBar() || ScbState() ) |
|
1880 { |
|
1881 return; |
|
1882 } |
|
1883 |
|
1884 CAknScrollBar* scrollBar = STATIC_CAST(CAknScrollBar*, iPageContainer->ScrollBar()->VerticalScrollBar()); |
|
1885 |
|
1886 if ( scrollBar ) |
|
1887 { |
|
1888 TEikScrollBarModel vertModel; |
|
1889 |
|
1890 // scrollbar's accuracy is one pixel |
|
1891 // TODO: replace iLines->MinimumSize with world size, presumably saved in CAknFormPhysics |
|
1892 vertModel.iScrollSpan = iLines->MinimumSize().iHeight; |
|
1893 vertModel.iThumbSpan = iSize.iHeight - iSize.iHeight % 2; |
|
1894 vertModel.iThumbPosition = Max( iPhysics->ViewTopY(), 0 ); |
|
1895 |
|
1896 iExtension->iPreviousThumbPosition = vertModel.iThumbPosition; |
|
1897 TRAP_IGNORE(scrollBar->SetModelL(&vertModel)); // won't leave now, but can't guarantee forever |
|
1898 iPageContainer->ScrollBar()->Tile(&vertModel); |
|
1899 iPageContainer->ScrollBar()->SetVFocusPosToThumbPos(vertModel.iThumbPosition); |
|
1900 } |
|
1901 } |
|
1902 |
|
1903 CCoeControl* CEikDialogPage::ComponentControl(TInt aIndex) const |
|
1904 { |
|
1905 if ( IsForm() && !iExtension->iHandlingResourceChange) |
|
1906 { |
|
1907 if ( iCurrentLine != -1 && !iExtension->iScrolling ) |
|
1908 { |
|
1909 return (*iLines)[iCurrentLine]; |
|
1910 } |
|
1911 |
|
1912 return NULL; |
|
1913 } |
|
1914 |
|
1915 // Ensure that the current line is the last control returned |
|
1916 if ( iCurrentLine != -1 ) |
|
1917 { |
|
1918 if ( aIndex == CountComponentControls() -1 ) |
|
1919 return ((*iLines)[iCurrentLine]); |
|
1920 else if ( aIndex < iCurrentLine ) |
|
1921 return ((*iLines)[aIndex]); |
|
1922 else |
|
1923 return ((*iLines)[aIndex+1]); |
|
1924 } |
|
1925 else |
|
1926 return((*iLines)[aIndex]); |
|
1927 } |
|
1928 |
|
1929 TInt CEikDialogPage::CountComponentControls() const |
|
1930 { |
|
1931 if ( IsForm() && !iExtension->iHandlingResourceChange) |
|
1932 { |
|
1933 if ( iCurrentLine != -1 && !iExtension->iScrolling ) |
|
1934 { |
|
1935 return 1; |
|
1936 } |
|
1937 |
|
1938 return 0; |
|
1939 } |
|
1940 |
|
1941 return iLines->Count(); |
|
1942 } |
|
1943 |
|
1944 void CEikDialogPage::PrepareForFocusTransitionL() |
|
1945 { |
|
1946 if (iPageObserver) |
|
1947 iPageObserver->PrepareForFocusTransitionL(); |
|
1948 } |
|
1949 |
|
1950 void CEikDialogPage::ReportPageChangedL() |
|
1951 { |
|
1952 if (iPageObserver) |
|
1953 iPageObserver->PageChangedL(PageId()); |
|
1954 } |
|
1955 |
|
1956 void CEikDialogPage::LineChangedL(TInt aControlId) |
|
1957 { |
|
1958 if (iPageObserver) |
|
1959 iPageObserver->LineChangedL(aControlId); |
|
1960 // update scrollbar |
|
1961 UpdateScrollBarL(); |
|
1962 PrepareToDrawVerticalLine(); |
|
1963 } |
|
1964 |
|
1965 void CEikDialogPage::ShowFocus(TBool aFocus, TBool aRedraw) |
|
1966 { |
|
1967 if (iCurrentLine>=0) |
|
1968 { |
|
1969 if ( iExtension && iExtension->iUsesSingleClick && aFocus ) |
|
1970 { |
|
1971 aFocus = HighlightVisible(); |
|
1972 } |
|
1973 |
|
1974 (*iLines)[iCurrentLine]->SetCurrent(aFocus, aRedraw); |
|
1975 |
|
1976 if (aRedraw) |
|
1977 (*iLines)[iCurrentLine]->DrawNow(); |
|
1978 else |
|
1979 (*iLines)[iCurrentLine]->DrawDeferred(); |
|
1980 } |
|
1981 } |
|
1982 |
|
1983 void CEikDialogPage::ChangeFocusTo(TInt aLineIndex) |
|
1984 { |
|
1985 TInt oldLine = iCurrentLine; |
|
1986 |
|
1987 if (aLineIndex==iCurrentLine) |
|
1988 return; |
|
1989 ShowFocus( EFalse, EFalse ); |
|
1990 iCurrentLine=aLineIndex; |
|
1991 ShowFocus(ETrue, EFalse ); |
|
1992 |
|
1993 if ( ( oldLine != iCurrentLine && IsForm() ) && |
|
1994 iExtension->iInitialLayoutDone ) |
|
1995 { |
|
1996 if ( oldLine != -1 ) |
|
1997 { |
|
1998 iLines->MoveLineToScreen( oldLine, 0, EFalse ); |
|
1999 RecordLineL( oldLine ); |
|
2000 } |
|
2001 |
|
2002 RecordLineL( iCurrentLine ); |
|
2003 iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue ); |
|
2004 } |
|
2005 } |
|
2006 |
|
2007 TInt CEikDialogPage::FindLineIndex(const CCoeControl* aControl) const |
|
2008 { |
|
2009 return(iLines->FindLineIndex(aControl)); |
|
2010 } |
|
2011 |
|
2012 /** |
|
2013 * Gets the list of logical colors employed in the drawing of the control, |
|
2014 * paired with an explanation of how they are used. Appends the list into aColorUseList. |
|
2015 */ |
|
2016 void CEikDialogPage::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const |
|
2017 { |
|
2018 TCoeColorUse colorUse; |
|
2019 colorUse.SetLogicalColor(EColorDialogBackground); |
|
2020 colorUse.SetUse(TCoeColorUse::EBack|TCoeColorUse::ESurrounds|TCoeColorUse::EActive|TCoeColorUse::ENormal|TCoeColorUse::ENeutral); |
|
2021 aColorUseList.AppendL(colorUse); |
|
2022 } |
|
2023 |
|
2024 /** |
|
2025 * Handles a change to the control's resources of type aType |
|
2026 * which are shared across the environment, e.g. colors or fonts. |
|
2027 */ |
|
2028 void CEikDialogPage::HandleResourceChange(TInt aType) |
|
2029 { |
|
2030 if ( aType==KEikDynamicLayoutVariantSwitch ) |
|
2031 { |
|
2032 const TInt numLines=iLines->Count(); |
|
2033 for ( TInt i=0; i < numLines; i++ ) |
|
2034 { |
|
2035 CEikCaptionedControl* thisLine=(*iLines)[i]; |
|
2036 thisLine->iControl->HandleResourceChange(aType); |
|
2037 } |
|
2038 } |
|
2039 |
|
2040 if ( aType != KEikDynamicLayoutVariantSwitch || !IsForm() ) |
|
2041 { |
|
2042 iExtension->iHandlingResourceChange = ETrue; |
|
2043 CCoeControl::HandleResourceChange(aType); |
|
2044 iExtension->iHandlingResourceChange = EFalse; |
|
2045 } |
|
2046 |
|
2047 // Removed, because disables transparency |
|
2048 if (!CAknEnv::Static()->TransparencyEnabled() || |
|
2049 (PageContainer()->PageSelector()->Dialg()->DialogFlags() & EEikDialogFlagFillAppClientRect || |
|
2050 PageContainer()->PageSelector()->Dialg()->DialogFlags() & EEikDialogFlagFillScreen) ) |
|
2051 { |
|
2052 Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorDialogBackground,*this)); |
|
2053 } |
|
2054 |
|
2055 if ( IsForm() ) |
|
2056 { |
|
2057 switch ( aType ) |
|
2058 { |
|
2059 case KEikDynamicLayoutVariantSwitch: |
|
2060 for ( TInt i = 0; i < iLines->Count(); ++i ) |
|
2061 { |
|
2062 (*iLines)[i]->HandleResourceChange( KEikDynamicLayoutVariantSwitch ); |
|
2063 } |
|
2064 |
|
2065 ReconsiderPageSize(); |
|
2066 |
|
2067 if ( iCurrentLine != KErrNotFound ) |
|
2068 { |
|
2069 if( iLastExposedLine != -1 ) |
|
2070 { |
|
2071 iLastExposedLineViewWinYPosition = iLines->LineIndexToYPosition( iLastExposedLine, 0 ); |
|
2072 } |
|
2073 |
|
2074 iExtension->iScrolling = EFalse; |
|
2075 ExposeLine( iCurrentLine, ETrue ); |
|
2076 (*iLines)[iCurrentLine]->DrawNow(); |
|
2077 } |
|
2078 |
|
2079 DrawDeferred(); |
|
2080 break; |
|
2081 |
|
2082 case KAknsMessageSkinChange: |
|
2083 ReconsiderPageSize(); |
|
2084 |
|
2085 if ( iCurrentLine != KErrNotFound ) |
|
2086 { |
|
2087 ExposeLine( iCurrentLine, ETrue ); |
|
2088 } |
|
2089 break; |
|
2090 |
|
2091 case KAknMessageFocusLost: |
|
2092 if ( !IsEditable() && iExtension && |
|
2093 iExtension->iUsesSingleClick && HighlightVisible() ) |
|
2094 { |
|
2095 HighlightVisible( EFalse ); |
|
2096 |
|
2097 CEikCaptionedControl* line = (*iLines)[iCurrentLine]; |
|
2098 |
|
2099 if ( line ) |
|
2100 { |
|
2101 ShowFocus( EFalse, ETrue ); |
|
2102 } |
|
2103 } |
|
2104 break; |
|
2105 |
|
2106 default: |
|
2107 break; |
|
2108 } |
|
2109 } |
|
2110 } |
|
2111 |
|
2112 CCoeControl* CEikDialogPage::Control(TInt aLineId) const |
|
2113 { |
|
2114 return(Line(aLineId)->iControl); |
|
2115 } |
|
2116 |
|
2117 CCoeControl* CEikDialogPage::ControlOrNull(TInt aLineId) const |
|
2118 { |
|
2119 TInt index=iLines->LineIndexFromId(aLineId); |
|
2120 if (index<0) |
|
2121 return(NULL); |
|
2122 return((*iLines)[index]->iControl); |
|
2123 } |
|
2124 |
|
2125 CEikCaptionedControl* CEikDialogPage::Line(TInt aLineId) const |
|
2126 { |
|
2127 CEikCaptionedControl* line=LineOrNull(aLineId); |
|
2128 if (line) |
|
2129 return line; |
|
2130 |
|
2131 ASSERT(EFalse); // Not found. |
|
2132 return NULL; |
|
2133 } |
|
2134 |
|
2135 CEikCaptionedControl* CEikDialogPage::LineOrNull(TInt aLineId) const |
|
2136 { |
|
2137 TInt index=iLines->LineIndexFromId(aLineId); |
|
2138 if (index<0) |
|
2139 return NULL; // Not found. |
|
2140 return((*iLines)[index]); |
|
2141 } |
|
2142 |
|
2143 CEikCaptionedControl* CEikDialogPage::CurrentLine() const |
|
2144 { |
|
2145 if (iCurrentLine>=0) |
|
2146 return (*iLines)[iCurrentLine]; |
|
2147 |
|
2148 return NULL; |
|
2149 } |
|
2150 |
|
2151 void CEikDialogPage::FocusChanged(TDrawNow /*aDrawNow*/) |
|
2152 { |
|
2153 if (iCurrentLine>=0 && !IsFocused()) |
|
2154 { |
|
2155 CEikCaptionedControl* currentLine=(*iLines)[iCurrentLine]; |
|
2156 currentLine->SetCurrent(EFalse); |
|
2157 } |
|
2158 } |
|
2159 |
|
2160 void CEikDialogPage::ResetLineMinimumSizes() |
|
2161 { |
|
2162 iLines->ResetMinimumSizes(); |
|
2163 } |
|
2164 |
|
2165 TKeyResponse CEikDialogPage::OfferHotKeysKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
2166 { |
|
2167 /* |
|
2168 Changed from offering the hot key to every control on the page in order of appearance, until |
|
2169 someone accepts the hotkey, to only offering the hot key to the current line and then, only if |
|
2170 it accepts hotkeys. |
|
2171 |
|
2172 Added Enter key as a special case... |
|
2173 */ |
|
2174 if ( (iCurrentLine!=-1) && (iCurrentLine < iLines->Count()) ) |
|
2175 if ( (*iLines)[iCurrentLine]->OfferHotKeys() || |
|
2176 (*iLines)[iCurrentLine]->TakesEnterKey() && (aKeyEvent.iCode==EKeyEnter) |
|
2177 ) |
|
2178 if (!IsForm()|| iIsEditable) |
|
2179 return (*iLines)[iCurrentLine]->iControl->OfferKeyEventL(aKeyEvent,aType); |
|
2180 return EKeyWasNotConsumed; |
|
2181 } |
|
2182 |
|
2183 TBool CEikDialogPage::TakesEnterKey() |
|
2184 { |
|
2185 if (iCurrentLine<0) |
|
2186 return EFalse; |
|
2187 return (*iLines)[iCurrentLine]->TakesEnterKey(); |
|
2188 } |
|
2189 |
|
2190 void CEikDialogPage::SetEditableL( TBool aEditable, TBool /*aActivePage*/ ) |
|
2191 { |
|
2192 // Tell each of the controls on the page (which are part of a form) of their editable state. |
|
2193 |
|
2194 iIsEditable = aEditable; |
|
2195 |
|
2196 HighlightVisible( aEditable ); |
|
2197 |
|
2198 if ( iExtension->iUsesSingleClick && iExtension->iSetInitialFocusDone ) |
|
2199 { |
|
2200 ShowFocus( EFalse ); |
|
2201 } |
|
2202 |
|
2203 const TInt numLines=iLines->Count() ; |
|
2204 /* if a form, no currently selected line, in edit mode, and there is a line |
|
2205 available (we know this as iLines->Count()>0), then select the first line. |
|
2206 */ |
|
2207 if ((iFormControl) && (iCurrentLine==-1) && |
|
2208 (aEditable) && (iLines->Count()>0)) |
|
2209 iCurrentLine=0; |
|
2210 for ( TInt ii = 0 ; ii < numLines ; ii++ ) |
|
2211 { |
|
2212 if ( (*iLines)[ii]->iIsFormControl ) |
|
2213 { |
|
2214 (*iLines)[ii]->SetEditableL( aEditable, !( iFormFlags & EEikFormHideEmptyFields ) ) ; |
|
2215 CEikCaptionedControl* theLine = (*iLines)[ii]; |
|
2216 if (theLine->ControlIsAnEdwin(theLine->iControlType)) |
|
2217 { |
|
2218 /* |
|
2219 Set the edwin out to have the correct width, but |
|
2220 @ Make the line invisible, to prevent redraws. |
|
2221 @ stop any edwin resize events being acted on (done by iIgnoreFurtherEdwinResizeEvents) |
|
2222 */ |
|
2223 iIgnoreFurtherEdwinResizeEvents=STATIC_CAST(CEikEdwin*,theLine->iControl); |
|
2224 theLine->MakeVisible(EFalse); |
|
2225 theLine->PositionFormComponents(); |
|
2226 theLine->MakeVisible(ETrue); |
|
2227 iIgnoreFurtherEdwinResizeEvents=0; |
|
2228 if (aEditable) |
|
2229 { |
|
2230 /* |
|
2231 Set the cursor position correctly for each edwin |
|
2232 @ if it's before the current line, set it to the end of the edwin |
|
2233 @ if it is or is after the current line, set it to the start of the edwin |
|
2234 */ |
|
2235 CEikEdwin* edwinPtr = STATIC_CAST(CEikEdwin*,theLine->iControl); |
|
2236 //filter enterkay. |
|
2237 //edwinPtr->AddFlagToUserFlags(CEikEdwin::ENoLineOrParaBreaks); |
|
2238 if (ii<=iCurrentLine) |
|
2239 edwinPtr->SetCursorPosL(edwinPtr->TextLength(),EFalse); |
|
2240 else |
|
2241 edwinPtr->SetCursorPosL(0,EFalse); |
|
2242 } |
|
2243 } |
|
2244 } |
|
2245 } |
|
2246 /* |
|
2247 if changing to view mode, |
|
2248 and the currentline is now non-focussing (invisible) |
|
2249 Then set iCurrentLine to the top focusable control |
|
2250 */ |
|
2251 if ((iFormControl)&&(!aEditable)&&(iCurrentLine!=-1)) |
|
2252 { |
|
2253 CEikCaptionedControl* line = (*iLines)[iCurrentLine]; |
|
2254 if (line->IsNonFocusing()) |
|
2255 { |
|
2256 // break the news to the old focussed line. |
|
2257 ShowFocus(EFalse, EFalse); |
|
2258 // now set the new currentline value. |
|
2259 iCurrentLine=TopFocusableLine(); |
|
2260 } |
|
2261 } |
|
2262 |
|
2263 if ( ( iCurrentLine >= 0 ) && ( (*iLines)[iCurrentLine]->iIsFormControl ) ) |
|
2264 (*iLines)[iCurrentLine]->SetCurrent( ETrue ) ; |
|
2265 |
|
2266 ReconsiderPageSize(); |
|
2267 |
|
2268 if ((iLines->Count()>0) && (iCurrentLine >= 0)) |
|
2269 { |
|
2270 ExposeLine(iCurrentLine,ETrue); |
|
2271 } |
|
2272 } |
|
2273 |
|
2274 TBool CEikDialogPage::AnythingToDisplay() const |
|
2275 { |
|
2276 // assume Form control... shouldnt be called otherwise (Panic?) |
|
2277 for (TInt i=0;i<iLines->Count();i++) |
|
2278 { |
|
2279 if ((*iLines)[i]->IsDisplayable()) |
|
2280 { |
|
2281 return ETrue; |
|
2282 }; |
|
2283 } |
|
2284 |
|
2285 return EFalse; |
|
2286 } |
|
2287 |
|
2288 // <SKIN> New function (Averell 2) to permit skinning the No Data screen. New AknDrawWithSkins() utility requires 'this' |
|
2289 void CEikDialogPage::DrawEmptyListL( CWindowGc& aGc ) |
|
2290 { |
|
2291 HBufC* dataBuffer=0; |
|
2292 dataBuffer=iEikonEnv->AllocReadResourceLC(R_AVKON_NO_DATA ); |
|
2293 AknDrawWithSkins::DrawEmptyList(TRect(TPoint(1,7),TPoint(177,135)),aGc,*dataBuffer, this ); |
|
2294 CleanupStack::PopAndDestroy(); // finished with current val of dataBuffer |
|
2295 } |
|
2296 |
|
2297 void CEikDialogPage::Draw(const TRect& /*aRect*/) const |
|
2298 { |
|
2299 if ( iFormControl ) |
|
2300 { |
|
2301 // added this to see if anything on the page is visible. |
|
2302 // if not, this is used to display the No data found screen. |
|
2303 TBool anythingToShow= AnythingToDisplay(); |
|
2304 |
|
2305 CWindowGc& windowGcRef = SystemGc(); // needed for DrawEmptyList |
|
2306 |
|
2307 if (!anythingToShow) |
|
2308 { |
|
2309 // Have to call non const leaving function... Ignore the TRAP as result is cosmetic only. |
|
2310 TRAP_IGNORE( const_cast<CEikDialogPage*>(this)->DrawEmptyListL( windowGcRef ) ) ; |
|
2311 } |
|
2312 else |
|
2313 DrawVerticalLine(); |
|
2314 |
|
2315 |
|
2316 if ( IsForm() ) |
|
2317 { |
|
2318 TInt delta = iPhysics->ViewCenter().iY; |
|
2319 delta -= iPhysics->ViewCenterDistance(); |
|
2320 TInt topY = delta; |
|
2321 delta *= -1; |
|
2322 |
|
2323 TAknLayoutRect formtLayoutRect; |
|
2324 formtLayoutRect.LayoutRect(Rect(), AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine()); |
|
2325 formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine()); |
|
2326 |
|
2327 |
|
2328 TRect targetRect( formtLayoutRect.Rect() ); |
|
2329 targetRect.iBr.iY = topY + targetRect.Height(); |
|
2330 targetRect.iTl.iY = topY; |
|
2331 |
|
2332 TInt lineToSkip = -1; |
|
2333 |
|
2334 if ( !iExtension->iScrolling ) |
|
2335 { |
|
2336 lineToSkip = iCurrentLine; |
|
2337 } |
|
2338 |
|
2339 iExtension->iRecordingGc->FlushBuffer( targetRect, lineToSkip ); |
|
2340 } |
|
2341 } |
|
2342 } |
|
2343 |
|
2344 void CEikDialogPage::AfterAddingNewLinesL(TInt aNewLineAdded) |
|
2345 { |
|
2346 /** |
|
2347 * void CEikDialogPage::AfterAddingNewLinesL(TInt aNewLineAdded) |
|
2348 * |
|
2349 * Context : Every time a line is added, this should be called |
|
2350 * |
|
2351 * Function: |
|
2352 * It is used to : |
|
2353 * #1 register the the dialog page with the caption control. |
|
2354 * #2 register the control on this line (e.g. an edwin) with the one above it |
|
2355 * #3 call Register component on the line, to set up listeners, etc. |
|
2356 * #4 Set the editable value to whatever the dialog page's editable value is. |
|
2357 */ |
|
2358 __ASSERT_DEBUG(iLines && (aNewLineAdded<=iLines->Count()), Panic(EEikDialogPanicErrorDuringAddingLine)); |
|
2359 if (aNewLineAdded== -1) |
|
2360 return; // line has not been added yet. |
|
2361 CEikCaptionedControl* lineAdded = iLines->At(aNewLineAdded); |
|
2362 // if aNewLineAdded is zero, then there is no line above, else set value. |
|
2363 CEikCaptionedControl* lineVisuallyAboveAndNumericallyBelow = |
|
2364 (!aNewLineAdded)? 0:iLines->At(aNewLineAdded-1); |
|
2365 // #1 |
|
2366 lineAdded->RegisterPageWithCaptionControl(this); |
|
2367 // #2 |
|
2368 if (lineVisuallyAboveAndNumericallyBelow && iLines->At(aNewLineAdded)->iControl) |
|
2369 // there is a line above this one and it has a control |
|
2370 lineAdded->iControl->SetNeighbor(lineVisuallyAboveAndNumericallyBelow->iControl); |
|
2371 // #3 |
|
2372 RegisterComponentL(lineAdded->iControlType, lineAdded->iControl, lineAdded); |
|
2373 // #4 |
|
2374 lineAdded->SetEditableL(iIsEditable); |
|
2375 |
|
2376 // The next is needed or phonebook's "add field" / date will not work correctly. |
|
2377 if (IsActivated()) |
|
2378 { |
|
2379 DrawDeferred(); |
|
2380 } |
|
2381 |
|
2382 if (iFormControl) |
|
2383 { |
|
2384 lineAdded->SetPictographCallBack(); |
|
2385 } |
|
2386 |
|
2387 if ( IsForm() ) |
|
2388 { |
|
2389 if ( aNewLineAdded < ( iLines->Count() - 1 ) ) |
|
2390 { |
|
2391 // new line was added as the last line |
|
2392 iExtension->iRecordingGc->InsertLineL( aNewLineAdded ); |
|
2393 } |
|
2394 else |
|
2395 { |
|
2396 // new line was inserted between existing line |
|
2397 iExtension->iRecordingGc->AppendLineL(); |
|
2398 } |
|
2399 } |
|
2400 |
|
2401 ExposeLine( aNewLineAdded, EFalse ); |
|
2402 |
|
2403 if ( IsForm() && iSize.iHeight != 0 && aNewLineAdded != -1 ) |
|
2404 iLines->MoveLineToScreen( aNewLineAdded, iPhysics->ViewTopY(), EFalse ); |
|
2405 } |
|
2406 |
|
2407 TInt CEikDialogPage::GetFormFlags() const |
|
2408 {return iFormFlags;}; |
|
2409 |
|
2410 void CEikDialogPage::SetFormFlag( TInt16 aFlag, TBool aEnable ) |
|
2411 { |
|
2412 if ( aFlag >= EFormResizeOptimisationFlag ) // Dynamic Flags only - static flags are unaffected. |
|
2413 { |
|
2414 if ( aEnable ) |
|
2415 iFormFlags |= aFlag ; |
|
2416 else if ( !aEnable ) |
|
2417 iFormFlags &= (~aFlag) ; |
|
2418 } |
|
2419 } |
|
2420 |
|
2421 CEikCaptionedControl* CEikDialogPage::LineOnPageOrNull(TInt aLine) const |
|
2422 { |
|
2423 if (iLines) // if iLines, and there are enough lines on the page |
|
2424 if (iLines->Count() > aLine) |
|
2425 return (*iLines)[aLine]; |
|
2426 return 0; |
|
2427 } |
|
2428 |
|
2429 void CEikDialogPage::RegisterComponentL(TInt aControlType, CCoeControl* aControl, CEikCaptionedControl* aLine) |
|
2430 { |
|
2431 /* |
|
2432 Private method to deal with registering components with forms/dialogs correctly so that |
|
2433 observers, etc are created. |
|
2434 */ |
|
2435 if ( aControl && aLine->ControlIsAnEdwin( aControlType ) ) |
|
2436 { |
|
2437 CEikEdwin* edwin=STATIC_CAST(CEikEdwin*,aControl); |
|
2438 edwin->SetEdwinSizeObserver( this ); |
|
2439 edwin->SetEdwinObserver( this ) ; |
|
2440 // Pre-empt the growth of Edwin. It mustn't get any bigger. |
|
2441 if ( !iFormControl ) |
|
2442 { |
|
2443 edwin->SetMaximumHeight( iSize.iHeight ); |
|
2444 } |
|
2445 } |
|
2446 if (aControl && |
|
2447 ( aControlType==EAknCtPopupField || aControlType==EAknCtPopupFieldText)) |
|
2448 { |
|
2449 CAknPopupField* popupField=0; |
|
2450 if (aControlType==EAknCtPopupField) |
|
2451 popupField = (CAknPopupField*)aControl ; |
|
2452 else |
|
2453 popupField = (CAknPopupFieldText*)aControl ; |
|
2454 popupField->SetPopupFieldObserver(this); |
|
2455 popupField->SetMaxNumberOfLinesPermitted(aLine->MaximumNumberOfControlLinesOnVisiblePage()); |
|
2456 } |
|
2457 if ( aControl && aLine->ControlIsAMfne( aControlType ) ) |
|
2458 { |
|
2459 aControl->SetObserver( this ); |
|
2460 } |
|
2461 if ( iFormControl ) |
|
2462 { |
|
2463 // Tell the line that it is on a form - activate it to enable it draw its highlight box |
|
2464 aLine->iIsFormControl = iFormControl ; |
|
2465 if ( iFormFlags ) |
|
2466 aLine->SetFormFlags( iFormFlags ) ; |
|
2467 |
|
2468 aLine->GetAknLayoutValuesL() ; // should cause the control to have size. |
|
2469 } |
|
2470 }; |
|
2471 |
|
2472 |
|
2473 void CEikDialogPage::SetPageContainer(const CEikDialogPageContainer* aPageContainer) |
|
2474 { |
|
2475 iPageContainer=aPageContainer; |
|
2476 } |
|
2477 |
|
2478 const CEikDialogPageContainer* CEikDialogPage::PageContainer() const |
|
2479 { |
|
2480 return iPageContainer; |
|
2481 } |
|
2482 |
|
2483 void CEikDialogPage::ReconsiderPageSize() |
|
2484 { |
|
2485 if ( !Rect().IsEmpty() ) |
|
2486 { |
|
2487 iLines->SetRect( Rect(), iScroll->Top(), iScroll->Middle(), iScroll->Bottom() ); |
|
2488 } |
|
2489 } |
|
2490 |
|
2491 EXPORT_C void CEikDialogPage::SetFormLayout(TFormLayoutSelection aLayout) |
|
2492 { |
|
2493 __ASSERT_DEBUG(iFormControl , Panic(EEikFormPanicSettingDoublePageFormLayoutOnNonForm)); |
|
2494 iFormLayout=aLayout; |
|
2495 }; |
|
2496 |
|
2497 EXPORT_C CEikDialogPage::TFormLayoutSelection CEikDialogPage::FormLayout() const |
|
2498 { |
|
2499 return iFormLayout; |
|
2500 } |
|
2501 |
|
2502 TBool CEikDialogPage::IsEditable() const |
|
2503 { |
|
2504 return iIsEditable; |
|
2505 } |
|
2506 |
|
2507 TBool CEikDialogPage::IsForm() const |
|
2508 { |
|
2509 return iFormControl; |
|
2510 } |
|
2511 |
|
2512 void CEikDialogPage::SetDoubleQuery(TBool aIsDoubleQuery) |
|
2513 { |
|
2514 iExtension->iIsDoubleQuery = aIsDoubleQuery; |
|
2515 } |
|
2516 |
|
2517 CEikFormAnim* CEikDialogPage::AcquireAnim( |
|
2518 TBool aAcquire, MEikFormAnimObserver* aObserver ) const |
|
2519 { |
|
2520 if( iPageContainer ) |
|
2521 return iPageContainer->AcquireAnim( aAcquire, aObserver ); |
|
2522 |
|
2523 return NULL; |
|
2524 } |
|
2525 |
|
2526 TBool CEikDialogPage::IsAtOrOffTopOfPage(const CCoeControl* aControl) const |
|
2527 { |
|
2528 if (!iLines||!aControl) |
|
2529 return EFalse; |
|
2530 TInt lineIndex = FindLineIndex(aControl); |
|
2531 if (lineIndex==-1) |
|
2532 return EFalse; |
|
2533 CEikCaptionedControl* capCtrl =(*iLines)[lineIndex]; |
|
2534 if (!capCtrl) |
|
2535 return EFalse; |
|
2536 if (capCtrl->Rect().iTl.iY<=0 ) |
|
2537 return ETrue; |
|
2538 else |
|
2539 return EFalse; |
|
2540 } |
|
2541 |
|
2542 TBool CEikDialogPage::IsAtOrOffBottomOfPage(const CCoeControl* aControl) const |
|
2543 { |
|
2544 if (!iLines|| !aControl) |
|
2545 return EFalse; |
|
2546 TInt lineIndex = FindLineIndex(aControl); |
|
2547 if (lineIndex==-1) |
|
2548 return EFalse; |
|
2549 CEikCaptionedControl* capCtrl =(*iLines)[lineIndex]; |
|
2550 if (!capCtrl) |
|
2551 return EFalse; |
|
2552 if (capCtrl->Rect().iBr.iY>=(iSize.iHeight)) |
|
2553 return ETrue; |
|
2554 else |
|
2555 return EFalse; |
|
2556 |
|
2557 } |
|
2558 |
|
2559 /* |
|
2560 return True if off the top |
|
2561 return False if off the top |
|
2562 */ |
|
2563 |
|
2564 TBool CEikDialogPage::VisibleSizeOnPage(TInt& aHeightOfControlVisibleOnPage, const CCoeControl* aControl) const |
|
2565 { |
|
2566 if (!iLines|| !aControl) |
|
2567 { |
|
2568 aHeightOfControlVisibleOnPage=0; |
|
2569 return EFalse; |
|
2570 } |
|
2571 TInt lineIndex = FindLineIndex(aControl); |
|
2572 if (lineIndex==-1) |
|
2573 { |
|
2574 aHeightOfControlVisibleOnPage=0; |
|
2575 return EFalse; |
|
2576 } |
|
2577 CEikCaptionedControl* capCtrl =(*iLines)[lineIndex]; |
|
2578 aHeightOfControlVisibleOnPage=capCtrl->Rect().Height(); |
|
2579 return EFalse; |
|
2580 } |
|
2581 |
|
2582 TSize CEikDialogPage::RealDataSize() const |
|
2583 { |
|
2584 if (iLines) |
|
2585 if (iLines->Count()>0) |
|
2586 return TRect((*iLines)[0]->Rect().iTl,(*iLines)[iLines->Count()-1]->Rect().iBr).Size(); |
|
2587 return iSize; |
|
2588 } |
|
2589 |
|
2590 TInt CEikDialogPage::NumberOfLines() const |
|
2591 { |
|
2592 if (iLines) |
|
2593 return iLines->Count(); |
|
2594 return 0; |
|
2595 } |
|
2596 |
|
2597 CEikCaptionedControl* CEikDialogPage::LineByIndex(TInt aIndex) const |
|
2598 { |
|
2599 if (iLines->Count() > aIndex && aIndex>=0) |
|
2600 return (*iLines)[aIndex]; |
|
2601 return 0; |
|
2602 } |
|
2603 |
|
2604 EXPORT_C void* CEikDialogPage::ExtensionInterface( TUid /*aInterface*/ ) |
|
2605 { |
|
2606 return NULL; |
|
2607 } |
|
2608 |
|
2609 // --------------------------------------------------------------------------- |
|
2610 // CEikDialogPage::HandleFormPointerEventL |
|
2611 // --------------------------------------------------------------------------- |
|
2612 // |
|
2613 void CEikDialogPage::HandleFormPointerEventL( const TPointerEvent& aPointerEvent ) |
|
2614 { |
|
2615 if ( LineHandlerCalled() ) |
|
2616 { |
|
2617 return; |
|
2618 } |
|
2619 |
|
2620 TInt touchedLine = iLines->YPositionToLineIndex( aPointerEvent.iPosition.iY + iPhysics->ViewTopY() ); |
|
2621 TBool callDefaultImplementation = ETrue; |
|
2622 |
|
2623 // Tapping form's empty area takes no action of any kind. Also bounce |
|
2624 // effect can't be stopped. |
|
2625 if ( ( aPointerEvent.iType == TPointerEvent::EButton1Down && touchedLine == KErrNotFound ) || !iPhysics->CanBeStopped() ) |
|
2626 { |
|
2627 IgnoreEventsUntilNextPointerUp(); |
|
2628 return; |
|
2629 } |
|
2630 |
|
2631 CEikCaptionedControl* newLine = NULL; |
|
2632 TInt controlType = KErrNotFound; |
|
2633 |
|
2634 if ( touchedLine != KErrNotFound ) |
|
2635 { |
|
2636 newLine = (*iLines)[touchedLine]; |
|
2637 controlType = newLine->iControlType; |
|
2638 } |
|
2639 |
|
2640 TBool textSelected = EFalse; |
|
2641 |
|
2642 if ( touchedLine != iCurrentLine && newLine && |
|
2643 !iExtension->iUsesSingleClick ) |
|
2644 { |
|
2645 if ( !newLine->ControlIsAPopfield( controlType ) ) |
|
2646 { |
|
2647 callDefaultImplementation = EFalse; |
|
2648 } |
|
2649 } |
|
2650 |
|
2651 if ( iCurrentLine != -1 && iCurrentLine == iExtension->iLastTouchedLine ) |
|
2652 { |
|
2653 CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine]; |
|
2654 |
|
2655 if ( currentLine->ControlIsAnEdwin( currentLine->iControlType ) ) |
|
2656 { |
|
2657 CEikEdwin* edwin = static_cast<CEikEdwin*>( currentLine->iControl ); |
|
2658 textSelected = edwin->SelectionLength(); |
|
2659 |
|
2660 if ( textSelected == edwin->TextLength() ) |
|
2661 { |
|
2662 textSelected = EFalse; |
|
2663 } |
|
2664 } |
|
2665 } |
|
2666 |
|
2667 if ( aPointerEvent.iType == TPointerEvent::EButton1Down && touchedLine != KErrNotFound ) |
|
2668 { |
|
2669 iExtension->iOldCenterY = iPhysics->ViewCenter().iY; |
|
2670 TInt bottom = iExtension->iOldCenterY + iSize.iHeight - iSize.iHeight / 2; |
|
2671 if ( bottom < 0 ) |
|
2672 { |
|
2673 iExtension->iBottomItem = -1; |
|
2674 } |
|
2675 else |
|
2676 { |
|
2677 iExtension->iBottomItem = bottom / (*iLines)[0]->Size().iHeight; |
|
2678 if ( iExtension->iBottomItem > iLines->Count() ) |
|
2679 { |
|
2680 iExtension->iBottomItem = iLines->Count(); |
|
2681 } |
|
2682 } |
|
2683 TInt upper = iExtension->iOldCenterY - iSize.iHeight / 2; |
|
2684 if ( upper <= 0 ) |
|
2685 { |
|
2686 iExtension->iTopItem = -1; |
|
2687 } |
|
2688 else |
|
2689 { |
|
2690 iExtension->iTopItem = upper / (*iLines)[0]->Size().iHeight; |
|
2691 if ( iExtension->iTopItem > iLines->Count() ) |
|
2692 { |
|
2693 iExtension->iTopItem = iLines->Count(); |
|
2694 } |
|
2695 } |
|
2696 iExtension->iScrolling = EFalse; |
|
2697 iExtension->HandleFormFeedback( this, aPointerEvent, touchedLine, iCurrentLine ); |
|
2698 |
|
2699 TBool wasScrolling = ( iPhysics->OngoingPhysicsAction() != |
|
2700 CAknPhysics::EAknPhysicsActionNone ); |
|
2701 iPhysics->Stop(); |
|
2702 iExtension->iLastTouchedLine = touchedLine; |
|
2703 iExtension->iDragStartPosition = aPointerEvent.iPosition; |
|
2704 iExtension->iLastPointerPos = aPointerEvent.iPosition; |
|
2705 iExtension->iStartTime.HomeTime(); |
|
2706 |
|
2707 if ( touchedLine != iCurrentLine ) |
|
2708 { |
|
2709 iExtension->iFocusedClicked = EFalse; |
|
2710 |
|
2711 if ( iExtension->iUsesSingleClick ) |
|
2712 { |
|
2713 if ( !wasScrolling ) |
|
2714 { |
|
2715 HighlightVisible( ETrue ); |
|
2716 HighlightTimerCallBack( this ); |
|
2717 } |
|
2718 } |
|
2719 else |
|
2720 { |
|
2721 iExtension->iHighlightTimer->Cancel(); |
|
2722 iExtension->iHighlightTimer->Start( |
|
2723 TTimeIntervalMicroSeconds32( iPhysics->HighlightDelay() * 1000 ), |
|
2724 TTimeIntervalMicroSeconds32( iPhysics->HighlightDelay() * 1000 ), |
|
2725 TCallBack( HighlightTimerCallBack, this ) ); |
|
2726 } |
|
2727 } |
|
2728 else |
|
2729 { |
|
2730 iExtension->iFocusedClicked = ETrue; |
|
2731 |
|
2732 if ( !IsEditable() && iExtension->iUsesSingleClick ) |
|
2733 { |
|
2734 CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine]; |
|
2735 |
|
2736 if ( currentLine ) |
|
2737 { |
|
2738 HighlightVisible( ETrue ); |
|
2739 ShowFocus( ETrue, ETrue ); |
|
2740 } |
|
2741 } |
|
2742 } |
|
2743 } |
|
2744 |
|
2745 if ( aPointerEvent.iType == TPointerEvent::EDrag ) |
|
2746 { |
|
2747 TPoint drag( iExtension->iDragStartPosition - aPointerEvent.iPosition ); |
|
2748 |
|
2749 if ( Abs( drag.iY ) > iPhysics->DragThreshold() ) |
|
2750 { |
|
2751 iExtension->iHighlightTimer->Cancel(); |
|
2752 |
|
2753 if ( !iExtension->iScrolling && !textSelected ) |
|
2754 { |
|
2755 if ( !IsEditable() && iExtension->iUsesSingleClick && |
|
2756 HighlightVisible() ) |
|
2757 { |
|
2758 HighlightVisible( EFalse ); |
|
2759 |
|
2760 CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine]; |
|
2761 |
|
2762 if ( currentLine ) |
|
2763 { |
|
2764 ShowFocus( EFalse, ETrue ); |
|
2765 } |
|
2766 } |
|
2767 |
|
2768 iExtension->iScrolling = ETrue; |
|
2769 iExtension->iScrolled = ETrue; |
|
2770 iExtension->iLastPointerPos = aPointerEvent.iPosition; |
|
2771 RemovePressedDownHighlight(); |
|
2772 iLines->MoveLineToScreen( iCurrentLine, 0, EFalse ); |
|
2773 callDefaultImplementation = EFalse; |
|
2774 } |
|
2775 } |
|
2776 |
|
2777 if ( iExtension->iScrolling ) |
|
2778 { |
|
2779 iPhysics->SetPanningPosition( |
|
2780 TPoint( 0, iExtension->iLastPointerPos.iY - aPointerEvent.iPosition.iY ) ); |
|
2781 iExtension->iLastPointerPos = aPointerEvent.iPosition; |
|
2782 } |
|
2783 //For secret editor display |
|
2784 CEikCaptionedControl* currentLine=(*iLines)[iCurrentLine]; |
|
2785 if( currentLine->ControlIsASecretEditor(currentLine->iControlType) ) |
|
2786 { |
|
2787 CEikSecretEditor* edwin=(CEikSecretEditor*)currentLine->iControl; |
|
2788 edwin->EnableCursor( EFalse ); |
|
2789 } |
|
2790 } |
|
2791 |
|
2792 if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
2793 { |
|
2794 iExtension->HandleFormFeedback( this, aPointerEvent, touchedLine, iCurrentLine ); |
|
2795 if ( !IsEditable() && iExtension->iUsesSingleClick && |
|
2796 HighlightVisible() ) |
|
2797 { |
|
2798 HighlightVisible( EFalse ); |
|
2799 |
|
2800 CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine]; |
|
2801 |
|
2802 if ( currentLine ) |
|
2803 { |
|
2804 ShowFocus( EFalse, ETrue ); |
|
2805 } |
|
2806 } |
|
2807 |
|
2808 TPoint drag( iExtension->iDragStartPosition - aPointerEvent.iPosition ); |
|
2809 |
|
2810 if ( !textSelected ) |
|
2811 { |
|
2812 if ( !iPhysics->StartFlick( drag, iExtension->iStartTime ) ) |
|
2813 { |
|
2814 iExtension->iScrolling = EFalse; |
|
2815 |
|
2816 if ( iPageObserver && GrabbingComponent() ) |
|
2817 { |
|
2818 iPageObserver->HandleDialogPageEventL( MEikDialogPageObserver::EDialogPageTapped ); |
|
2819 } |
|
2820 } |
|
2821 else |
|
2822 { |
|
2823 callDefaultImplementation = EFalse; |
|
2824 |
|
2825 if ( !iExtension->iScrolling ) |
|
2826 { |
|
2827 // feedback is given every time when new item |
|
2828 // appears to the screen -> follows the visual feedback |
|
2829 iExtension->SilentFeedback( this, ETouchFeedbackSensitiveList, aPointerEvent ); |
|
2830 // It might happen that there are no drag events between down and |
|
2831 // up if the distance is short enough. |
|
2832 iExtension->iHighlightTimer->Cancel(); |
|
2833 iExtension->iScrolling = ETrue; |
|
2834 iExtension->iScrolled = ETrue; |
|
2835 iLines->MoveLineToScreen( iCurrentLine, 0, EFalse ); |
|
2836 RemovePressedDownHighlight(); |
|
2837 } |
|
2838 } |
|
2839 } |
|
2840 } |
|
2841 |
|
2842 // forward pointer event to line's observer |
|
2843 if ( touchedLine == iCurrentLine && newLine && |
|
2844 ( iExtension->iFocusedClicked || |
|
2845 ( !IsEditable() && iExtension->iUsesSingleClick ) ) && |
|
2846 !iExtension->iScrolling ) |
|
2847 { |
|
2848 MPointerEventObserver* observer = newLine->PointerEventObserver(); |
|
2849 |
|
2850 if ( observer ) |
|
2851 { |
|
2852 iExtension->iFlags.Set( CDialogPageExtension::ELineHandlerCalled ); |
|
2853 observer->PointerEvent( newLine, aPointerEvent ); |
|
2854 iExtension->iFlags.Clear( CDialogPageExtension::ELineHandlerCalled ); |
|
2855 } |
|
2856 } |
|
2857 |
|
2858 TBool mskPress = EFalse; |
|
2859 |
|
2860 // If the stylus is up above already focused line - emulate an MSK press |
|
2861 if ( iFormControl && !iIsEditable && // in view mode |
|
2862 aPointerEvent.iType == TPointerEvent::EButton1Up && |
|
2863 touchedLine == iCurrentLine && |
|
2864 ( iExtension->iFocusedClicked || iExtension->iUsesSingleClick ) && |
|
2865 !iExtension->iScrolling ) |
|
2866 { |
|
2867 mskPress = ETrue; |
|
2868 callDefaultImplementation = EFalse; |
|
2869 } |
|
2870 |
|
2871 if ( callDefaultImplementation && ( iExtension->iFocusedClicked || |
|
2872 iExtension->iUsesSingleClick ) && newLine ) |
|
2873 { |
|
2874 if ( newLine->ControlIsAPopfield( controlType ) ) |
|
2875 { |
|
2876 if(aPointerEvent.iType == TPointerEvent::EButton1Down) |
|
2877 { |
|
2878 newLine->HandlePointerEventL(aPointerEvent); |
|
2879 iExtension->iCapturingItem = touchedLine; |
|
2880 } |
|
2881 else if(aPointerEvent.iType == TPointerEvent::EButton1Up) |
|
2882 { |
|
2883 newLine->HandlePointerEventL(aPointerEvent); |
|
2884 } |
|
2885 } |
|
2886 else |
|
2887 { |
|
2888 CCoeControl::HandlePointerEventL( aPointerEvent ); |
|
2889 } |
|
2890 } |
|
2891 |
|
2892 if ( mskPress ) |
|
2893 { |
|
2894 TKeyEvent key; |
|
2895 key.iCode=EKeyOK; |
|
2896 key.iModifiers=0; |
|
2897 key.iRepeats = 0; |
|
2898 CEikonEnv::Static()->SimulateKeyEventL( key, EEventKey ); |
|
2899 } |
|
2900 } |
|
2901 |
|
2902 |
|
2903 // --------------------------------------------------------------------------- |
|
2904 // CEikDialogPage::UpdatePhysics |
|
2905 // --------------------------------------------------------------------------- |
|
2906 // |
|
2907 void CEikDialogPage::UpdatePhysics() |
|
2908 { |
|
2909 if ( IsForm() ) |
|
2910 { |
|
2911 TPoint viewCenter( iSize.iWidth / 2, 0 ); |
|
2912 |
|
2913 if ( iLines->Count() > 0 ) |
|
2914 { |
|
2915 viewCenter.iY = Abs( (*iLines)[0]->Rect().iTl.iY - iPosition.iY ); |
|
2916 } |
|
2917 |
|
2918 viewCenter.iY += iPhysics->ViewCenterDistance(); |
|
2919 |
|
2920 if ( iExtension->iInitialLayoutDone ) |
|
2921 { |
|
2922 TInt oldScreenHeight = iPhysics->ViewSize().iHeight; |
|
2923 TInt delta = ( iPhysics->ViewCenterDistance() ) - |
|
2924 ( oldScreenHeight / 2 ); |
|
2925 |
|
2926 viewCenter = iPhysics->ViewCenter(); |
|
2927 viewCenter.iY += delta; |
|
2928 } |
|
2929 |
|
2930 TSize worldSize( iLines->MinimumSize() ); |
|
2931 worldSize.iHeight = Max( worldSize.iHeight, iSize.iHeight ); |
|
2932 |
|
2933 TRAP_IGNORE( iPhysics->InitPhysicsL( worldSize, iSize, viewCenter ) ); |
|
2934 TRAP_IGNORE( UpdateScrollBarL() ); |
|
2935 } |
|
2936 } |
|
2937 |
|
2938 |
|
2939 // --------------------------------------------------------------------------- |
|
2940 // CEikDialogPage::HighlightTimerCallBack |
|
2941 // --------------------------------------------------------------------------- |
|
2942 // |
|
2943 TInt CEikDialogPage::HighlightTimerCallBack( TAny* aPtr ) |
|
2944 { |
|
2945 CEikDialogPage* me = static_cast<CEikDialogPage*>( aPtr ); |
|
2946 me->HandleHighlightTimer(); |
|
2947 |
|
2948 return 0; |
|
2949 } |
|
2950 |
|
2951 |
|
2952 // --------------------------------------------------------------------------- |
|
2953 // CEikDialogPage::HandleHighlightTimer |
|
2954 // --------------------------------------------------------------------------- |
|
2955 // |
|
2956 void CEikDialogPage::HandleHighlightTimer() |
|
2957 { |
|
2958 iExtension->iHighlightTimer->Cancel(); |
|
2959 |
|
2960 TInt touchedLine = iExtension->iLastTouchedLine; |
|
2961 |
|
2962 if ( ( touchedLine < iLines->Count() ) && ( touchedLine != iCurrentLine ) ) |
|
2963 { |
|
2964 (*iLines)[touchedLine]->ActivateL(); |
|
2965 |
|
2966 if ( LineIsFocusable( touchedLine ) ) |
|
2967 { |
|
2968 TRAP_IGNORE( PrepareForFocusTransitionL() ); |
|
2969 ChangeFocusToAndExposeL( touchedLine ); |
|
2970 LineChangedL( (*iLines)[touchedLine]->iId ); |
|
2971 } |
|
2972 } |
|
2973 } |
|
2974 |
|
2975 |
|
2976 |
|
2977 // --------------------------------------------------------------------------- |
|
2978 // CEikDialogPage::HighlightVisible |
|
2979 // --------------------------------------------------------------------------- |
|
2980 // |
|
2981 TBool CEikDialogPage::HighlightVisible() const |
|
2982 { |
|
2983 if ( IsEditable() || !iExtension->iUsesSingleClick ) |
|
2984 { |
|
2985 return ETrue; |
|
2986 } |
|
2987 |
|
2988 return iHighlightVisible; |
|
2989 } |
|
2990 |
|
2991 |
|
2992 // --------------------------------------------------------------------------- |
|
2993 // CEikDialogPage::ScrollCacheByPixels |
|
2994 // --------------------------------------------------------------------------- |
|
2995 // |
|
2996 void CEikDialogPage::ScrollCacheByPixels( |
|
2997 TInt /*aDelta*/, const TDesC& /*aDebugMsg*/, TBool aDrawNow ) |
|
2998 { |
|
2999 if ( iLines->Count() <= 0 ) |
|
3000 return; |
|
3001 TInt bottomItem, upperItem; |
|
3002 TInt bottom = iPhysics->ViewCenter().iY + iSize.iHeight - iSize.iHeight / 2; |
|
3003 if ( bottom < 0 ) |
|
3004 { |
|
3005 bottomItem = -1; |
|
3006 } |
|
3007 else |
|
3008 { |
|
3009 bottomItem = bottom / (*iLines)[0]->Size().iHeight; |
|
3010 if ( bottomItem > iLines->Count() ) |
|
3011 { |
|
3012 bottomItem = iLines->Count(); |
|
3013 } |
|
3014 } |
|
3015 TInt upper = iPhysics->ViewCenter().iY - iSize.iHeight / 2; |
|
3016 if ( upper <= 0 ) |
|
3017 { |
|
3018 upperItem = -1; |
|
3019 } |
|
3020 else |
|
3021 { |
|
3022 upperItem = upper / (*iLines)[0]->Size().iHeight; |
|
3023 if ( upperItem > iLines->Count() ) |
|
3024 { |
|
3025 upperItem = iLines->Count(); |
|
3026 } |
|
3027 } |
|
3028 if ( iPhysics->OngoingPhysicsAction() != CAknPhysics::EAknPhysicsActionNone ) |
|
3029 { |
|
3030 if ( upperItem == -1 || bottomItem == iLines->Count() ) |
|
3031 { |
|
3032 if ( upperItem != iExtension->iTopItem || bottomItem != iExtension->iBottomItem ) |
|
3033 { |
|
3034 iExtension->SilentFeedback( this, ETouchFeedbackSensitiveList, TPointerEvent() ); |
|
3035 } |
|
3036 } |
|
3037 else if ( upperItem >= 0 || bottomItem < iLines->Count() ) |
|
3038 { |
|
3039 if ( upperItem < iExtension->iTopItem || bottomItem > iExtension->iBottomItem ) |
|
3040 { |
|
3041 iExtension->SilentFeedback( this, ETouchFeedbackSensitiveList, TPointerEvent() ); |
|
3042 } |
|
3043 } |
|
3044 } |
|
3045 iExtension->iBottomItem = bottomItem; |
|
3046 iExtension->iTopItem = upperItem; |
|
3047 if ( aDrawNow ) |
|
3048 { |
|
3049 TRAP_IGNORE( UpdateScrollBarL() ); |
|
3050 DrawNow(); |
|
3051 } |
|
3052 } |
|
3053 |
|
3054 |
|
3055 // --------------------------------------------------------------------------- |
|
3056 // CEikDialogPage::UpdateLineInCache |
|
3057 // --------------------------------------------------------------------------- |
|
3058 // |
|
3059 void CEikDialogPage::UpdateLineInCache( CEikCaptionedControl* aLine ) |
|
3060 { |
|
3061 TInt lineIndex = iLines->FindLineIndex( aLine ); |
|
3062 |
|
3063 if ( lineIndex != KErrNotFound ) |
|
3064 { |
|
3065 if ( aLine->Position() != TPoint( 1000, 0 ) ) |
|
3066 { |
|
3067 iExtension->iRecordingGc->SetLineRect( lineIndex, TRect( TPoint( 1000, 0 ), aLine->Rect().Size() ) ); |
|
3068 } |
|
3069 else |
|
3070 { |
|
3071 iExtension->iRecordingGc->SetLineRect( lineIndex, aLine->Rect() ); |
|
3072 iExtension->iRecordingGc->PurgeLine( lineIndex ); |
|
3073 |
|
3074 Parent()->Parent()->Parent()->SetCustomGc( iExtension->iRecordingGc ); |
|
3075 |
|
3076 aLine->DrawForeground( aLine->Rect() ); |
|
3077 DrawControl( aLine ); |
|
3078 |
|
3079 Parent()->Parent()->Parent()->SetCustomGc( NULL ); |
|
3080 } |
|
3081 } |
|
3082 |
|
3083 if ( iExtension->iInitialLayoutDone ) |
|
3084 { |
|
3085 UpdatePhysics(); |
|
3086 } |
|
3087 } |
|
3088 |
|
3089 |
|
3090 // --------------------------------------------------------------------------- |
|
3091 // CEikDialogPage::Synchronize |
|
3092 // --------------------------------------------------------------------------- |
|
3093 // |
|
3094 void CEikDialogPage::Synchronize() |
|
3095 { |
|
3096 iExtension->iScrolling = EFalse; |
|
3097 iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue ); |
|
3098 } |
|
3099 |
|
3100 |
|
3101 // --------------------------------------------------------------------------- |
|
3102 // CEikDialogPage::DrawControl |
|
3103 // --------------------------------------------------------------------------- |
|
3104 // |
|
3105 void CEikDialogPage::DrawControl( CCoeControl* aControl ) const |
|
3106 { |
|
3107 TInt count = aControl->CountComponentControls(); |
|
3108 RDrawableWindow* parentWindow = aControl->DrawableWindow(); |
|
3109 |
|
3110 for ( TInt i = 0; i < count; ++i ) |
|
3111 { |
|
3112 CCoeControl* control = aControl->ComponentControl( i ); |
|
3113 RDrawableWindow* childWindow = control->DrawableWindow(); |
|
3114 |
|
3115 // Test whether child control has its own window. In that case skip |
|
3116 // recording since child windows can't be scrolled. |
|
3117 if ( parentWindow->WsHandle() != childWindow->WsHandle() ) |
|
3118 { |
|
3119 continue; |
|
3120 } |
|
3121 |
|
3122 control->DrawForeground( control->Rect() ); |
|
3123 DrawControl( control ); |
|
3124 } |
|
3125 } |
|
3126 |
|
3127 |
|
3128 // --------------------------------------------------------------------------- |
|
3129 // CEikDialogPage::RecordLinesL |
|
3130 // --------------------------------------------------------------------------- |
|
3131 // |
|
3132 void CEikDialogPage::RecordLinesL() |
|
3133 { |
|
3134 Parent()->Parent()->Parent()->SetCustomGc( iExtension->iRecordingGc ); |
|
3135 |
|
3136 iExtension->iRecordingGc->PurgeBuffer(); |
|
3137 |
|
3138 CEikCaptionedControl* line = NULL; |
|
3139 |
|
3140 for ( TInt i = 0; i < iLines->Count(); ++i ) |
|
3141 { |
|
3142 line = (*iLines)[i]; |
|
3143 iExtension->iRecordingGc->PrepareForNewLineL( line->Rect() ); |
|
3144 line->DrawForeground( line->Rect() ); |
|
3145 DrawControl( line ); |
|
3146 } |
|
3147 |
|
3148 Parent()->Parent()->Parent()->SetCustomGc( NULL ); |
|
3149 } |
|
3150 |
|
3151 |
|
3152 // --------------------------------------------------------------------------- |
|
3153 // CEikDialogPage::RecordLineL |
|
3154 // --------------------------------------------------------------------------- |
|
3155 // |
|
3156 void CEikDialogPage::RecordLineL( TInt aLine ) |
|
3157 { |
|
3158 Parent()->Parent()->Parent()->SetCustomGc( iExtension->iRecordingGc ); |
|
3159 |
|
3160 CEikCaptionedControl* line = (*iLines)[aLine]; |
|
3161 |
|
3162 if ( line ) |
|
3163 { |
|
3164 iExtension->iRecordingGc->ReplaceLineL( aLine ); |
|
3165 line->DrawForeground( (line->Rect() ) ); |
|
3166 DrawControl( line ); |
|
3167 } |
|
3168 |
|
3169 Parent()->Parent()->Parent()->SetCustomGc( NULL ); |
|
3170 } |
|
3171 |
|
3172 |
|
3173 // --------------------------------------------------------------------------- |
|
3174 // CEikDialogPage::ScrollByPixels |
|
3175 // --------------------------------------------------------------------------- |
|
3176 // |
|
3177 void CEikDialogPage::ScrollByPixels( TInt aDelta ) |
|
3178 { |
|
3179 if ( aDelta != 0 ) |
|
3180 { |
|
3181 iLines->ScrollByPixels( aDelta ); |
|
3182 TRAP_IGNORE( UpdateScrollBarL() ); |
|
3183 DrawNow(); |
|
3184 TRAP_IGNORE( RecordLinesL() ); |
|
3185 } |
|
3186 } |
|
3187 |
|
3188 |
|
3189 // --------------------------------------------------------------------------- |
|
3190 // CEikDialogPage::RemovePressedDownHighlight |
|
3191 // --------------------------------------------------------------------------- |
|
3192 // |
|
3193 void CEikDialogPage::RemovePressedDownHighlight() |
|
3194 { |
|
3195 if ( iCurrentLine != -1 ) |
|
3196 { |
|
3197 CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine]; |
|
3198 |
|
3199 if ( currentLine && currentLine->PressedDownState() ) |
|
3200 { |
|
3201 currentLine->SetPressedDownState( EFalse ); |
|
3202 if ( IsForm() ) |
|
3203 { |
|
3204 RecordLineL( iCurrentLine ); |
|
3205 } |
|
3206 } |
|
3207 } |
|
3208 } |
|
3209 |
|
3210 |
|
3211 // --------------------------------------------------------------------------- |
|
3212 // CEikDialogPage::HighlightVisible |
|
3213 // --------------------------------------------------------------------------- |
|
3214 // |
|
3215 void CEikDialogPage::HighlightVisible( TBool aVisible ) |
|
3216 { |
|
3217 if ( !IsEditable() ) |
|
3218 { |
|
3219 iHighlightVisible = aVisible; |
|
3220 } |
|
3221 } |
|
3222 |
|
3223 |
|
3224 //------------------------------------------------------------------------------------ |
|
3225 // CEikDialogPage::HandlePointerEventL() |
|
3226 // Function notifys the pages observer that the page has been tapped. (stylus down&up) |
|
3227 // The first tap to a dialog line sets focus to it (on stylus down),the second tap |
|
3228 // on the same line emulates an MSK press (on stylus up). It works also when the dialog |
|
3229 // is just opened and the (first) focused line is tapped. Any dragging to another line |
|
3230 // prevents the MSK press emulation on the subsequent stylus up event. |
|
3231 |
|
3232 // iExtension->iFocusClicked is used as a flag to indicate that the focus was previously |
|
3233 // moved to the current line. At the function beginning, if the stylus is down on the same |
|
3234 // line as the previous time, it means the current line is focused, and an MSK press must |
|
3235 // be emulated on the stylus up event. If iExtension->iFocusClicked is not set at a stylus |
|
3236 // up event, nothing happens: it means that the previous stylus down event just moved |
|
3237 // the focus to this line. |
|
3238 |
|
3239 |
|
3240 /* |
|
3241 Tactile feedback changes here potentially affect |
|
3242 - forms - can be distinquished with IsForm(). Feedback is handled here |
|
3243 - notes and notifiers - own feedback implementation-> should not be handled here |
|
3244 - queries - own feedback implementation -> should not be handled here |
|
3245 - sct - own feedback implementation-> should not be handled here |
|
3246 - popup form - no need for feedback |
|
3247 - color selection grid - own feedback implementation-> should not be handled here |
|
3248 |
|
3249 and of course any 3rd party stuff, which can not be reasonably handled here without |
|
3250 knowing how the 3rd party stuff should work. |
|
3251 |
|
3252 ---> only trigger feedback for form here. Anything else will be wrong. |
|
3253 */ |
|
3254 |
|
3255 |
|
3256 //------------------------------------------------------------------------------------ |
|
3257 // |
|
3258 void CEikDialogPage::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
3259 { |
|
3260 // Forms have their own specialized pointer event handling if panning and flicking |
|
3261 // are enabled. |
|
3262 if ( IsForm() ) |
|
3263 { |
|
3264 HandleFormPointerEventL( aPointerEvent ); |
|
3265 return; |
|
3266 } |
|
3267 // Pointer event is not handled at all if the dialog page has no lines. If an event |
|
3268 // would be handled in such situation if would crash in several places inside this |
|
3269 // method and the methods called from here. Also in some occasions such a dialog page |
|
3270 // indicates that the dialog is not fully constructed yet. |
|
3271 |
|
3272 // Leaving pointer event handling undone is quite safe assumption since a dialog without |
|
3273 // lines is empty. There's nothing that could happen when such a dialog is tapped e.g. |
|
3274 // it can't be dismissed since it doesn't have any CAknNoteControls etc. And if a client |
|
3275 // application wanted to alter this behaviour it would need to override this method anyway. |
|
3276 if( !AknLayoutUtils::PenEnabled() || iLines->Count() == 0 || LineHandlerCalled() ) |
|
3277 { |
|
3278 return; |
|
3279 } |
|
3280 |
|
3281 if ( PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.IsSet( CEikDialogExtension::EUseVirtualInput ) ) |
|
3282 { |
|
3283 PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.Set( CEikDialogExtension::EDelayedExit ); |
|
3284 } |
|
3285 |
|
3286 CCoeControl* grabbingComponent = GrabbingComponent(); |
|
3287 TBool callDefaultImplementation = ETrue; |
|
3288 TBool focusItem = EFalse; |
|
3289 // YPosToLine is scaled to iDataWinPos, so add it to pointer Y position |
|
3290 TInt yPosition = aPointerEvent.iPosition.iY; // + iDataWinPos.iY; |
|
3291 TInt touchedLineIndex = YPosToLine2( yPosition ); |
|
3292 // If the stylus is down and the touched line is already the current one, |
|
3293 // mark this fact in iExtension->iFocusedClicked to be used later when the stylus is up. |
|
3294 |
|
3295 if ( touchedLineIndex != KErrNotFound && |
|
3296 iExtension->iCapturingItem != KErrNotFound && |
|
3297 touchedLineIndex != iExtension->iCapturingItem ) |
|
3298 { |
|
3299 iExtension->iCapturingItem = KErrNotFound; |
|
3300 } |
|
3301 |
|
3302 // Click outside of items - do nothing |
|
3303 if ( touchedLineIndex == KErrNotFound ) |
|
3304 { |
|
3305 // Pan & flick capturing pointer events |
|
3306 if ( iExtension->iCapturingItem != KErrNotFound ) |
|
3307 { |
|
3308 CEikCaptionedControl* capturingItem = |
|
3309 (*iLines)[iExtension->iCapturingItem]; |
|
3310 const TInt type ( capturingItem->iControlType ); |
|
3311 if ( capturingItem->ControlIsAPopfield( type ) ) |
|
3312 { |
|
3313 capturingItem->iControl->HandlePointerEventL( aPointerEvent ); |
|
3314 if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
3315 { |
|
3316 iExtension->iCapturingItem = KErrNotFound; |
|
3317 } |
|
3318 } |
|
3319 } |
|
3320 |
|
3321 if( aPointerEvent.iType == TPointerEvent::EDrag || aPointerEvent.iType == TPointerEvent::EButtonRepeat ) |
|
3322 { |
|
3323 TInt numLines=iLines->Count(); |
|
3324 for (TInt ii=0;ii<numLines;ii++) |
|
3325 { |
|
3326 //If dragging out of forms, no pressed down effect. |
|
3327 CEikCaptionedControl* thisLine=(*iLines)[ii]; |
|
3328 const TInt controlType(thisLine->iControlType); |
|
3329 if(thisLine->ControlIsAnEdwin(controlType) || thisLine->ControlIsAMfne(controlType)) |
|
3330 { |
|
3331 if( thisLine->PressedDownState() ) |
|
3332 { |
|
3333 thisLine->SetPressedDownState( EFalse ); |
|
3334 thisLine->DrawDeferred(); |
|
3335 } |
|
3336 } |
|
3337 } |
|
3338 CAknControl::HandlePointerEventL(aPointerEvent); |
|
3339 } |
|
3340 // Forward point up event also. |
|
3341 if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
3342 { |
|
3343 CAknControl::HandlePointerEventL(aPointerEvent); |
|
3344 } |
|
3345 return; |
|
3346 } |
|
3347 |
|
3348 if ( aPointerEvent.iType == TPointerEvent::EButton1Down && |
|
3349 iCurrentLine == touchedLineIndex ) |
|
3350 { |
|
3351 iExtension->iFocusedClicked = ETrue; |
|
3352 } |
|
3353 |
|
3354 if ( (NumberOfLines() > 0 && !grabbingComponent) || |
|
3355 (IsForm() && !iIsEditable) ) |
|
3356 { |
|
3357 CEikCaptionedControl *currCtrl = (*iLines)[touchedLineIndex]; |
|
3358 MPointerEventObserver *obs = currCtrl->PointerEventObserver(); |
|
3359 TBool ret = ETrue; |
|
3360 if (obs) |
|
3361 { |
|
3362 iExtension->iFlags.Set( CDialogPageExtension::ELineHandlerCalled ); |
|
3363 ret = obs->PointerEvent(currCtrl, aPointerEvent); |
|
3364 iExtension->iFlags.Clear( CDialogPageExtension::ELineHandlerCalled ); |
|
3365 } |
|
3366 |
|
3367 // first move highlight to correct dialog line |
|
3368 if ( ret && touchedLineIndex != iCurrentLine ) |
|
3369 { |
|
3370 // activate line. |
|
3371 (*iLines)[touchedLineIndex]->ActivateL(); |
|
3372 |
|
3373 // focus line if it is possible, PointerUp have not cause scrolling. |
|
3374 if ( LineIsFocusable(touchedLineIndex) && |
|
3375 aPointerEvent.iType != TPointerEvent::EButton1Up ) |
|
3376 { |
|
3377 focusItem = ETrue; |
|
3378 |
|
3379 CEikCaptionedControl* newLine = (*iLines)[touchedLineIndex]; |
|
3380 const TInt controlType(newLine->iControlType); |
|
3381 |
|
3382 // all other than colorselection grid or popupfield does just move highlight. |
|
3383 // CSelGrid have also focus to clicked color |
|
3384 if ( !newLine->ControlIsAColourSelGrid(controlType) && |
|
3385 !newLine->ControlIsAPopfield(controlType) ) |
|
3386 { |
|
3387 callDefaultImplementation = EFalse; |
|
3388 } |
|
3389 } |
|
3390 } |
|
3391 } |
|
3392 |
|
3393 // If the stylus is dragged to a new line, focus that line and |
|
3394 // cancel the "Focused line clicked" mode (if any) for the next |
|
3395 // stylus up event (then no MSK press will be emulated) |
|
3396 if ( ( aPointerEvent.iType == TPointerEvent::EDrag || |
|
3397 aPointerEvent.iType == TPointerEvent::EButtonRepeat ) && |
|
3398 touchedLineIndex != iCurrentLine ) |
|
3399 { |
|
3400 if ( !(*iLines)[touchedLineIndex]->IsNonFocusing() ) |
|
3401 { |
|
3402 focusItem = ETrue; |
|
3403 } |
|
3404 |
|
3405 iExtension->iFocusedClicked = EFalse; |
|
3406 } |
|
3407 |
|
3408 // Click handling |
|
3409 |
|
3410 TBool mskPress = EFalse; |
|
3411 // If the stylus is up above already focused line - emulate an MSK press |
|
3412 if ( iFormControl && !iIsEditable && // in view mode |
|
3413 aPointerEvent.iType == TPointerEvent::EButton1Up && |
|
3414 touchedLineIndex == iCurrentLine && |
|
3415 iExtension->iFocusedClicked ) |
|
3416 { |
|
3417 mskPress = ETrue; |
|
3418 iExtension->iFocusedClicked = EFalse; |
|
3419 } |
|
3420 |
|
3421 /** |
|
3422 * The local @c destroyed variable keeps track of the object destroyed state. |
|
3423 */ |
|
3424 TBool destroyed = EFalse; |
|
3425 |
|
3426 if ( callDefaultImplementation ) |
|
3427 { |
|
3428 CEikCaptionedControl* currentLine = (*iLines)[touchedLineIndex]; |
|
3429 const TInt controlType(currentLine->iControlType); |
|
3430 |
|
3431 iExtension->iDestroyedPtr = &destroyed; |
|
3432 if ( currentLine->ControlIsAPopfield(controlType) ) |
|
3433 { |
|
3434 if(aPointerEvent.iType == TPointerEvent::EButton1Down) |
|
3435 { |
|
3436 currentLine->HandlePointerEventL(aPointerEvent); |
|
3437 iExtension->iCapturingItem = touchedLineIndex; |
|
3438 } |
|
3439 else if(aPointerEvent.iType == TPointerEvent::EButton1Up) |
|
3440 { |
|
3441 currentLine->HandlePointerEventL(aPointerEvent); |
|
3442 } |
|
3443 } |
|
3444 else |
|
3445 { |
|
3446 CCoeControl::HandlePointerEventL(aPointerEvent); |
|
3447 } |
|
3448 if ( !destroyed ) |
|
3449 { |
|
3450 iExtension->iDestroyedPtr = NULL; |
|
3451 } |
|
3452 else |
|
3453 { |
|
3454 return; |
|
3455 } |
|
3456 } |
|
3457 |
|
3458 if (iCurrentLine >= 0) |
|
3459 { |
|
3460 CEikCaptionedControl *ctrl = (*iLines)[iCurrentLine]; |
|
3461 const TInt ctrlType(ctrl->iControlType); |
|
3462 if (ctrl->ControlIsAPopfield(ctrlType)) |
|
3463 { |
|
3464 CAknPopupField::EAknPopupFieldSelectionMode mode = ((CAknPopupField*)ctrl->iControl)->SelectionMode(); |
|
3465 if (mode == CAknPopupField::EAknPopupFieldSelectionListMode) |
|
3466 { |
|
3467 focusItem = EFalse; |
|
3468 } |
|
3469 } |
|
3470 } |
|
3471 |
|
3472 TBool clear = EFalse; |
|
3473 if ( PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.IsSet( CEikDialogExtension::EUseVirtualInput ) ) |
|
3474 { |
|
3475 clear = ETrue; |
|
3476 } |
|
3477 |
|
3478 if ( focusItem || iExtension->iFocusedClicked) |
|
3479 { |
|
3480 iExtension->HandleFormFeedback( this, aPointerEvent, touchedLineIndex, iCurrentLine ); |
|
3481 } |
|
3482 |
|
3483 if ( focusItem ) |
|
3484 { |
|
3485 PrepareForFocusTransitionL(); |
|
3486 |
|
3487 (*iLines)[iCurrentLine]->ScrollBackEditor(); |
|
3488 ShowFocus( EFalse, EFalse ); |
|
3489 iCurrentLine = touchedLineIndex; |
|
3490 ShowFocus( ETrue, EFalse ); |
|
3491 ExposeLine( iCurrentLine, EFalse ); |
|
3492 LineChangedL((*iLines)[touchedLineIndex]->iId); |
|
3493 } |
|
3494 |
|
3495 else if (iPageObserver && grabbingComponent && aPointerEvent.iType == TPointerEvent::EButton1Up) |
|
3496 { |
|
3497 iPageObserver->HandleDialogPageEventL(MEikDialogPageObserver::EDialogPageTapped); |
|
3498 } |
|
3499 |
|
3500 if (mskPress) |
|
3501 { |
|
3502 TKeyEvent key; |
|
3503 key.iCode=EKeyOK; |
|
3504 key.iModifiers=0; |
|
3505 key.iRepeats = 0; |
|
3506 CEikonEnv::Static()->SimulateKeyEventL(key, EEventKey); |
|
3507 // SimulateKeyEventL has to be last, because it can |
|
3508 // possibly delete the dialog.. Must not do anything |
|
3509 // to the dialog after the call. |
|
3510 } |
|
3511 |
|
3512 if ( clear ) |
|
3513 { |
|
3514 PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.Clear( CEikDialogExtension::EDelayedExit ); |
|
3515 } |
|
3516 } |
|
3517 |
|
3518 void CEikDialogPage::SetScbState(TBool aExternal) |
|
3519 { |
|
3520 iExtension->iExternalScrollbar = aExternal; |
|
3521 } |
|
3522 |
|
3523 TBool CEikDialogPage::ScbState() const |
|
3524 { |
|
3525 return iExtension->iExternalScrollbar; |
|
3526 } |
|
3527 |
|
3528 // |
|
3529 // CEikDialogPageContainer. |
|
3530 // |
|
3531 |
|
3532 CEikDialogPageContainer::~CEikDialogPageContainer() |
|
3533 { |
|
3534 AKNTASHOOK_REMOVE(); |
|
3535 delete iAnimation; |
|
3536 if(iPageArray) |
|
3537 iPageArray->ResetAndDestroy(); |
|
3538 delete iPageArray; |
|
3539 delete iSBFrame; |
|
3540 } |
|
3541 |
|
3542 CEikDialogPageContainer* CEikDialogPageContainer::NewL(const CCoeControl& aParent,MEikDialogPageObserver* aPageObserver) |
|
3543 { |
|
3544 CEikDialogPageContainer* self=CEikDialogPageContainer::NewLC(aParent,aPageObserver); |
|
3545 CleanupStack::Pop(); |
|
3546 return self; |
|
3547 } |
|
3548 |
|
3549 CEikDialogPageContainer* CEikDialogPageContainer::NewLC(const CCoeControl& aParent,MEikDialogPageObserver* aPageObserver) |
|
3550 { |
|
3551 CEikDialogPageContainer* self=new(ELeave) CEikDialogPageContainer(aPageObserver); |
|
3552 CleanupStack::PushL(self); |
|
3553 self->ConstructL(aParent); |
|
3554 AKNTASHOOK_ADDL( self, "CEikDialogPageContainer" ); |
|
3555 return self; |
|
3556 } |
|
3557 |
|
3558 CEikDialogPageContainer::CEikDialogPageContainer(MEikDialogPageObserver* aPageObserver) |
|
3559 : iPageObserver(aPageObserver),iActivePage(0), iForm(EFalse) |
|
3560 { |
|
3561 SetHitTest( this ); |
|
3562 } |
|
3563 |
|
3564 void CEikDialogPageContainer::CommonConstructL(const CCoeControl& aParent) |
|
3565 { |
|
3566 iContext=this; |
|
3567 SetContainerWindowL( aParent ); |
|
3568 CreatePageArrayL(); |
|
3569 } |
|
3570 |
|
3571 void CEikDialogPageContainer::ConstructL(const CCoeControl& aParent) |
|
3572 { |
|
3573 CommonConstructL(aParent); |
|
3574 } |
|
3575 |
|
3576 void CEikDialogPageContainer::ConstructFromResourceL(TResourceReader& aReader,const CCoeControl& aParent) |
|
3577 { |
|
3578 CommonConstructL(aParent); |
|
3579 |
|
3580 const TInt numPages=aReader.ReadInt16(); |
|
3581 for (TInt ii=0;ii<numPages;ii++) |
|
3582 { |
|
3583 AddPageL(ii,aReader); |
|
3584 } |
|
3585 } |
|
3586 |
|
3587 void CEikDialogPageContainer::CreatePageArrayL() |
|
3588 { |
|
3589 iPageArray=new(ELeave) CArrayPtrFlat<CEikDialogPage>(KPageArrayGranularity); |
|
3590 } |
|
3591 |
|
3592 void CEikDialogPageContainer::CreateScrollBarL(const CCoeControl& aParent) |
|
3593 { |
|
3594 if (!iSBFrame) |
|
3595 { |
|
3596 iSBFrame=new(ELeave) CEikScrollBarFrame((CCoeControl*)&aParent, NULL, ETrue); |
|
3597 iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse, ETrue, EFalse); // window owning scrollbar |
|
3598 iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto); |
|
3599 iSBFrame->SetScrollBarFrameFlags(CEikScrollBarFrame::EVVisible); |
|
3600 iSBFrame->DrawBackground( EFalse, EFalse ); |
|
3601 } |
|
3602 } |
|
3603 |
|
3604 void CEikDialogPageContainer::SetActivePageByIdL(TInt aPageId) |
|
3605 { |
|
3606 // ToDo : unroll this loop |
|
3607 const TInt numPages=iPageArray->Count(); |
|
3608 for (TInt ii=0;ii<numPages;ii++) |
|
3609 { |
|
3610 CEikDialogPage* thisPage=(*iPageArray)[ii]; |
|
3611 if (thisPage->PageId()==aPageId) |
|
3612 { |
|
3613 if (iActivePage>=0) |
|
3614 (*iPageArray)[iActivePage]->SetInactiveL(); |
|
3615 thisPage->SetActiveAndFocusL(); |
|
3616 if(iActivePage!=ii) |
|
3617 { |
|
3618 thisPage->ReportPageChangedL(); |
|
3619 iActivePage=ii; |
|
3620 } |
|
3621 return; |
|
3622 } |
|
3623 } |
|
3624 |
|
3625 ASSERT(EFalse); // aPageId not found. |
|
3626 } |
|
3627 |
|
3628 void CEikDialogPageContainer::SetActivePageByIndexL(TInt aPageIndex) |
|
3629 { |
|
3630 const TInt numPages=iPageArray->Count(); |
|
3631 |
|
3632 if(aPageIndex>=0 && aPageIndex<numPages) |
|
3633 { |
|
3634 CArrayPtr<CEikDialogPage>& pageArray = *iPageArray; |
|
3635 if (iActivePage>=0) |
|
3636 pageArray[iActivePage]->SetInactiveL(); |
|
3637 pageArray[aPageIndex]->SetActiveAndFocusL(); |
|
3638 if(iActivePage!=aPageIndex) |
|
3639 { |
|
3640 pageArray[aPageIndex]->ReportPageChangedL(); |
|
3641 iActivePage=aPageIndex; |
|
3642 } |
|
3643 return; |
|
3644 } |
|
3645 |
|
3646 ASSERT(EFalse); // aPageIndex not found. |
|
3647 } |
|
3648 |
|
3649 TInt CEikDialogPageContainer::ActivateFirstPageL() |
|
3650 { |
|
3651 // Activate first page that isn't dimmed. |
|
3652 // SetToolTips() ; |
|
3653 const TInt numPages=iPageArray->Count(); |
|
3654 for (TInt ii=0;ii<numPages;ii++) |
|
3655 { |
|
3656 CEikDialogPage* thisPage=(*iPageArray)[ii]; |
|
3657 if (!(thisPage->IsDimmed())) |
|
3658 { |
|
3659 if (iActivePage>=0) |
|
3660 (*iPageArray)[iActivePage]->SetInactiveL(); |
|
3661 thisPage->SetActiveAndFocusL(); |
|
3662 if(iActivePage!=ii) |
|
3663 { |
|
3664 thisPage->ReportPageChangedL(); |
|
3665 iActivePage=ii; |
|
3666 } |
|
3667 return thisPage->PageId(); |
|
3668 } |
|
3669 } |
|
3670 |
|
3671 // All dimmed, so activate first. |
|
3672 CEikDialogPage* firstPage=(*iPageArray)[0]; |
|
3673 if (iActivePage>=0) |
|
3674 (*iPageArray)[iActivePage]->SetInactiveL(); |
|
3675 firstPage->SetActiveAndFocusL(); |
|
3676 if(iActivePage!=0) |
|
3677 { |
|
3678 firstPage->ReportPageChangedL(); |
|
3679 iActivePage=0; |
|
3680 } |
|
3681 return firstPage->PageId(); |
|
3682 } |
|
3683 |
|
3684 TInt CEikDialogPageContainer::PageId(TInt aIndex) const |
|
3685 |
|
3686 { |
|
3687 return (*iPageArray)[aIndex]->PageId(); |
|
3688 } |
|
3689 |
|
3690 TInt CEikDialogPageContainer::PageIdFromLineId(TInt aLineId) const |
|
3691 { |
|
3692 const TInt numPages=iPageArray->Count(); |
|
3693 for (TInt ii=0;ii<numPages;ii++) |
|
3694 { |
|
3695 CEikDialogPage* thisPage=(*iPageArray)[ii]; |
|
3696 if (thisPage->OwnsLine(aLineId)) |
|
3697 return thisPage->PageId(); |
|
3698 } |
|
3699 |
|
3700 return KErrNotFound; |
|
3701 } |
|
3702 |
|
3703 TBool CEikDialogPageContainer::SetInitialFocus() |
|
3704 { |
|
3705 TBool pageAcceptedFocus=(*iPageArray)[iActivePage]->SetInitialFocus(); |
|
3706 |
|
3707 if (pageAcceptedFocus) |
|
3708 SetFocus(ETrue,ENoDrawNow); |
|
3709 |
|
3710 return pageAcceptedFocus; |
|
3711 } |
|
3712 |
|
3713 void CEikDialogPageContainer::AddPageL(TInt aPageId) |
|
3714 { |
|
3715 CEikDialogPage* newPage=CEikDialogPage::NewLC(aPageId,Window(),*iSBFrame,*this,iPageObserver); |
|
3716 newPage->SetObserver(Observer()); |
|
3717 newPage->MakeVisible(EFalse); |
|
3718 if(iPageArray->Count()) |
|
3719 newPage->MakeVisible(EFalse); |
|
3720 iPageArray->AppendL(newPage); |
|
3721 CleanupStack::Pop(); |
|
3722 newPage->SetPageContainer(this); |
|
3723 } |
|
3724 |
|
3725 void CEikDialogPageContainer::AddPageL(TInt aPageId,TResourceReader& aReader) |
|
3726 { |
|
3727 CEikDialogPage* newPage=CEikDialogPage::NewLC(aPageId,Window(),*iSBFrame,*this,iPageObserver,aReader); |
|
3728 newPage->SetObserver(Observer()); |
|
3729 newPage->CopyControlContextFrom(this); |
|
3730 if(iPageArray->Count()) |
|
3731 newPage->MakeVisible(EFalse); |
|
3732 iPageArray->AppendL(newPage); |
|
3733 CleanupStack::Pop(); |
|
3734 newPage->SetPageContainer(this); |
|
3735 } |
|
3736 |
|
3737 CEikCaptionedControl* CEikDialogPageContainer::Line(TInt aLineId) const |
|
3738 { |
|
3739 CEikCaptionedControl* line=LineOrNull(aLineId); |
|
3740 if (line) |
|
3741 return line; |
|
3742 |
|
3743 ASSERT(EFalse); // Not found. |
|
3744 return NULL; |
|
3745 } |
|
3746 |
|
3747 CEikCaptionedControl* CEikDialogPageContainer::LineOrNull(TInt aLineId) const |
|
3748 { |
|
3749 CEikCaptionedControl* line=NULL; |
|
3750 const TInt numPages=iPageArray->Count(); |
|
3751 for (TInt ii=0;ii<numPages;ii++) |
|
3752 { |
|
3753 line=(*iPageArray)[ii]->LineOrNull(aLineId); |
|
3754 if (line) |
|
3755 return line; |
|
3756 } |
|
3757 |
|
3758 return NULL; // Not found. |
|
3759 } |
|
3760 |
|
3761 CEikCaptionedControl* CEikDialogPageContainer::CurrentLine() const |
|
3762 { |
|
3763 if(iActivePage>=0) |
|
3764 return (*iPageArray)[iActivePage]->CurrentLine(); |
|
3765 else |
|
3766 return NULL; |
|
3767 } |
|
3768 |
|
3769 void CEikDialogPageContainer::SetPageDensePacked(TInt aPageId,TBool aDensePacked) |
|
3770 { |
|
3771 (*iPageArray)[PageIndex(aPageId)]->SetDensePacking(aDensePacked); |
|
3772 } |
|
3773 |
|
3774 void CEikDialogPageContainer::SetAllPagesDensePacked(TBool aDensePacked) |
|
3775 { |
|
3776 const TInt numPages=iPageArray->Count(); |
|
3777 for (TInt ii=0;ii<numPages;ii++) |
|
3778 (*iPageArray)[ii]->SetDensePacking(aDensePacked); |
|
3779 } |
|
3780 |
|
3781 void CEikDialogPageContainer::SetPageDimmed(TInt aPageId,TBool aDimmed,TDrawNow aDrawNow) |
|
3782 { |
|
3783 CEikDialogPage* pageToDim=(*iPageArray)[PageIndex(aPageId)]; |
|
3784 pageToDim->SetDimmed(aDimmed); |
|
3785 if (aDrawNow==EDrawNow) |
|
3786 pageToDim->DrawNow(); |
|
3787 } |
|
3788 |
|
3789 TInt CEikDialogPageContainer::PageIndex(TInt aPageId) const |
|
3790 { |
|
3791 const TInt numPages=iPageArray->Count(); |
|
3792 for (TInt ii=0;ii<numPages;ii++) |
|
3793 { |
|
3794 if ((*iPageArray)[ii]->PageId()==aPageId) |
|
3795 return ii; |
|
3796 } |
|
3797 |
|
3798 return KErrNotFound; |
|
3799 } |
|
3800 |
|
3801 TInt CEikDialogPageContainer::LineId(const CCoeControl& aControl) const |
|
3802 { |
|
3803 const TInt numPages=iPageArray->Count(); |
|
3804 for (TInt ii=0;ii<numPages;ii++) |
|
3805 { |
|
3806 TInt thisId=(*iPageArray)[ii]->LineId(aControl); |
|
3807 if (thisId!=KErrNotFound) |
|
3808 return thisId; |
|
3809 } |
|
3810 |
|
3811 return KErrNotFound; |
|
3812 } |
|
3813 |
|
3814 TBool CEikDialogPageContainer::IsActivePageDimmed() const |
|
3815 { |
|
3816 return (*iPageArray)[iActivePage]->IsDimmed(); |
|
3817 } |
|
3818 |
|
3819 void CEikDialogPageContainer::InsertLineL(TInt aPosition,TInt aPageId,TInt aResourceId) |
|
3820 { |
|
3821 TInt pageIndex; |
|
3822 |
|
3823 if (aPageId==0) |
|
3824 pageIndex=iActivePage; |
|
3825 else |
|
3826 pageIndex=PageIndex(aPageId); |
|
3827 |
|
3828 (*iPageArray)[pageIndex]->InsertLineL(aPosition,aResourceId); |
|
3829 } |
|
3830 |
|
3831 void CEikDialogPageContainer::DeleteLine(TInt aLineId, TBool aRedraw) |
|
3832 { |
|
3833 (*iPageArray)[PageIndex(PageIdFromLineId(aLineId))]->DeleteLine(aLineId, aRedraw); |
|
3834 } |
|
3835 |
|
3836 void CEikDialogPageContainer::AdjustAllIds(TInt aPageId,TInt aControlIdDelta) |
|
3837 { |
|
3838 (*iPageArray)[PageIndex(aPageId)]->AdjustAllIds(aControlIdDelta); |
|
3839 } |
|
3840 |
|
3841 CCoeControl* CEikDialogPageContainer::CreateLineByTypeL(const TDesC& aCaption,TInt aLineId,TInt aControlType,TAny* aReturnValue) |
|
3842 { |
|
3843 return (*iPageArray)[iActivePage]->CreateLineByTypeL(aCaption,aLineId,aControlType,aReturnValue); |
|
3844 } |
|
3845 |
|
3846 CCoeControl* CEikDialogPageContainer::CreateLineByTypeL(const TDesC& aCaption,TInt aPageId,TInt aLineId,TInt aControlType,TAny* aReturnValue) |
|
3847 { |
|
3848 TInt pageIndex = PageIndex(aPageId); |
|
3849 ASSERT(pageIndex >= 0 && (*iPageArray)[pageIndex]); |
|
3850 CCoeControl* control=(*iPageArray)[pageIndex]->CreateLineByTypeL(aCaption,aLineId,aControlType,aReturnValue); |
|
3851 return control; |
|
3852 } |
|
3853 |
|
3854 TInt CEikDialogPageContainer::FocusLineL(TInt aLineId) |
|
3855 // |
|
3856 // If a page change is required, returns the new page index. |
|
3857 // Else returns -1. |
|
3858 // |
|
3859 { |
|
3860 // Try active page first. |
|
3861 TInt lineFocused=(*iPageArray)[iActivePage]->FocusLineL(aLineId); |
|
3862 if (lineFocused==KErrNone) |
|
3863 return -1; |
|
3864 |
|
3865 // Line not found. |
|
3866 ASSERT(EFalse); |
|
3867 return EFalse; |
|
3868 } |
|
3869 |
|
3870 TInt CEikDialogPageContainer::FindPageIndexForLineId(TInt aLineId) |
|
3871 // |
|
3872 // If a page change is required, returns the new page index. |
|
3873 // Else returns -1. |
|
3874 { |
|
3875 // Try active page first. |
|
3876 TInt lineIndex=(*iPageArray)[iActivePage]->LineIndex(aLineId); |
|
3877 if (lineIndex!=KErrNotFound) |
|
3878 return -1; |
|
3879 |
|
3880 const TInt numPages=iPageArray->Count(); |
|
3881 for (TInt ii=0;ii<numPages;ii++) |
|
3882 { |
|
3883 CEikDialogPage* thisPage=(*iPageArray)[ii]; |
|
3884 |
|
3885 if (ii!=iActivePage) |
|
3886 lineIndex=thisPage->LineIndex(aLineId); |
|
3887 |
|
3888 if (lineIndex!=KErrNotFound) |
|
3889 { |
|
3890 return ii; |
|
3891 } |
|
3892 } |
|
3893 |
|
3894 // Line not found. |
|
3895 ASSERT(EFalse); |
|
3896 return EFalse; |
|
3897 } |
|
3898 |
|
3899 TInt CEikDialogPageContainer::FocusedLineId() const |
|
3900 { |
|
3901 return (*iPageArray)[iActivePage]->FocusedLineId(); |
|
3902 } |
|
3903 |
|
3904 void CEikDialogPageContainer::GetAutoValues() |
|
3905 { |
|
3906 const TInt numPages=iPageArray->Count(); |
|
3907 for (TInt ii=0;ii<numPages;ii++) |
|
3908 (*iPageArray)[ii]->GetAutoValues(); |
|
3909 } |
|
3910 |
|
3911 void CEikDialogPageContainer::Draw(const TRect& /*aRect*/) const |
|
3912 { |
|
3913 } |
|
3914 |
|
3915 TInt CEikDialogPageContainer::NumPages() const |
|
3916 { |
|
3917 return iPageArray->Count(); |
|
3918 } |
|
3919 |
|
3920 void CEikDialogPageContainer::SizeChanged() |
|
3921 { |
|
3922 TRect rect( Rect() ); |
|
3923 const TInt numPages = iPageArray->Count(); |
|
3924 |
|
3925 for ( TInt i = 0; i < numPages; ++i ) |
|
3926 { |
|
3927 (*iPageArray)[i]->SetRect( rect ); |
|
3928 } |
|
3929 } |
|
3930 |
|
3931 TKeyResponse CEikDialogPageContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
3932 { |
|
3933 return (*iPageArray)[iActivePage]->OfferKeyEventL(aKeyEvent,aType); |
|
3934 } |
|
3935 |
|
3936 TKeyResponse CEikDialogPageContainer::OfferUpDownKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType,CEikDialogPage::TFocusNavigationMode aFocusNavigationMode) |
|
3937 { |
|
3938 return (*iPageArray)[iActivePage]->OfferUpDownKeyEventL(aKeyEvent,aType,aFocusNavigationMode); |
|
3939 } |
|
3940 |
|
3941 TInt CEikDialogPageContainer::ActivePageId() const |
|
3942 { |
|
3943 return (*iPageArray)[iActivePage]->PageId(); |
|
3944 } |
|
3945 |
|
3946 TInt CEikDialogPageContainer::ActivePageIndex() const |
|
3947 { |
|
3948 return iActivePage; |
|
3949 } |
|
3950 |
|
3951 TSize CEikDialogPageContainer::MinimumSize() |
|
3952 { |
|
3953 // The DPC reports a minimum size that is the max of all its contained DPs, independently |
|
3954 // for height and width |
|
3955 |
|
3956 TSize minSize(0,0); |
|
3957 |
|
3958 TInt numPages=iPageArray->Count(); |
|
3959 for (TInt ii=0;ii<numPages;ii++) |
|
3960 { |
|
3961 TSize thisPageSize((*iPageArray)[ii]->MinimumSize()); |
|
3962 if (thisPageSize.iWidth>minSize.iWidth) |
|
3963 minSize.iWidth=thisPageSize.iWidth; |
|
3964 if (thisPageSize.iHeight>minSize.iHeight) |
|
3965 minSize.iHeight=thisPageSize.iHeight; |
|
3966 } |
|
3967 |
|
3968 // Comment by RSD 11.09.2001: The following looks like the min size is never allowed to |
|
3969 // shrink... |
|
3970 minSize.iHeight=Max(minSize.iHeight,iSize.iHeight); |
|
3971 minSize.iWidth=Max(minSize.iWidth,iSize.iWidth); |
|
3972 return minSize; |
|
3973 } |
|
3974 |
|
3975 void CEikDialogPageContainer::PrepareForFocusLossL() |
|
3976 { |
|
3977 (*iPageArray)[iActivePage]->PrepareForFocusLossL(); |
|
3978 } |
|
3979 |
|
3980 TInt CEikDialogPageContainer::CountComponentControls() const |
|
3981 { |
|
3982 TInt i = 0; |
|
3983 if (iSBFrame) |
|
3984 i = iSBFrame->CountComponentControls(); |
|
3985 return (iActivePage>=0 ? 1 : 0) + i; |
|
3986 } |
|
3987 |
|
3988 CCoeControl* CEikDialogPageContainer::ComponentControl(TInt aIndex) const |
|
3989 { |
|
3990 if (aIndex==0 && iActivePage>=0) |
|
3991 return (*iPageArray)[iActivePage]; |
|
3992 |
|
3993 __ASSERT_ALWAYS(iSBFrame, User::Invariant()); |
|
3994 |
|
3995 return iSBFrame->ComponentControl(aIndex-(iActivePage>=0?1:0)); |
|
3996 } |
|
3997 |
|
3998 TSize CEikDialogPageContainer::PreferredSize(const TSize& aMaxSize) const |
|
3999 { |
|
4000 TSize preferredSize(0,0); |
|
4001 |
|
4002 const TInt numPages=iPageArray->Count(); |
|
4003 for (TInt ii=0;ii<numPages;ii++) |
|
4004 { |
|
4005 TSize thisPageSize((*iPageArray)[ii]->PreferredSize()); |
|
4006 if (thisPageSize.iWidth>preferredSize.iWidth) |
|
4007 preferredSize.iWidth=thisPageSize.iWidth; |
|
4008 if (thisPageSize.iHeight>preferredSize.iHeight) |
|
4009 preferredSize.iHeight=thisPageSize.iHeight; |
|
4010 } |
|
4011 |
|
4012 preferredSize.iWidth=Min(aMaxSize.iWidth,preferredSize.iWidth); |
|
4013 |
|
4014 return preferredSize; |
|
4015 } |
|
4016 |
|
4017 void CEikDialogPageContainer::ActivateL() |
|
4018 { |
|
4019 // Pass the activate event to child controls always. |
|
4020 CCoeControl::ActivateL(); |
|
4021 // |
|
4022 // Have to do this here instead of CEikCaptionedControl::ActivateL, because CaptionedControl has no |
|
4023 // activateL overridden. |
|
4024 const TInt numPages=iPageArray->Count(); |
|
4025 |
|
4026 for (TInt ii=0;ii<numPages;ii++) |
|
4027 { |
|
4028 CEikDialogPage *page = (*iPageArray)[ii]; |
|
4029 TInt numLines = page->NumberOfLines(); |
|
4030 for(int i=0;i<numLines;i++) |
|
4031 { |
|
4032 CEikCaptionedControl *capCC = page->LineByIndex(i); |
|
4033 |
|
4034 if ( capCC->iIsFormControl && page->FindLineIndex(page->CurrentLine()) != i) |
|
4035 { |
|
4036 |
|
4037 if (capCC->ControlIsAnEdwin(capCC->iControlType)) |
|
4038 { |
|
4039 CEikEdwin *edwin = (CEikEdwin*)capCC->iControl; |
|
4040 TRAP_IGNORE(edwin->TextView()->SetDocPosL(0) |
|
4041 ); |
|
4042 } |
|
4043 } |
|
4044 } |
|
4045 } |
|
4046 } |
|
4047 |
|
4048 void CEikDialogPageContainer::FocusChanged(TDrawNow aDrawNow) |
|
4049 { |
|
4050 (*iPageArray)[iActivePage]->SetFocus(IsFocused(),aDrawNow); |
|
4051 } |
|
4052 |
|
4053 void CEikDialogPageContainer::PrepareContext(CWindowGc& /*aGc*/) const |
|
4054 { |
|
4055 } |
|
4056 |
|
4057 void CEikDialogPageContainer::ResetLineMinimumSizes() |
|
4058 { |
|
4059 (*iPageArray)[iActivePage]->ResetLineMinimumSizes(); |
|
4060 } |
|
4061 |
|
4062 TInt CEikDialogPageContainer::FindLineIndex(const CCoeControl& aControl) const |
|
4063 { |
|
4064 CCoeControl* nonConstControlPtr=CONST_CAST(CCoeControl*,&aControl); |
|
4065 return (*iPageArray)[iActivePage]->FindLineIndex(nonConstControlPtr); |
|
4066 } |
|
4067 |
|
4068 TBool CEikDialogPageContainer::RotateFocusByL(TInt aDelta) |
|
4069 { |
|
4070 return (*iPageArray)[iActivePage]->RotateFocusByL(aDelta); |
|
4071 } |
|
4072 |
|
4073 TKeyResponse CEikDialogPageContainer::OfferHotKeysKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
4074 { |
|
4075 return (*iPageArray)[iActivePage]->OfferHotKeysKeyEventL(aKeyEvent,aType); |
|
4076 } |
|
4077 |
|
4078 TBool CEikDialogPageContainer::TakesEnterKey() |
|
4079 { |
|
4080 return (*iPageArray)[iActivePage]->TakesEnterKey(); |
|
4081 } |
|
4082 |
|
4083 CEikDialogPage* CEikDialogPageContainer::Page( TInt aPageID ) |
|
4084 { |
|
4085 // Try returning index, not pageID |
|
4086 if ( aPageID >=1 ) |
|
4087 return (*iPageArray)[ aPageID - 1 ] ; |
|
4088 else |
|
4089 // Single page only |
|
4090 return ( *iPageArray )[ aPageID ] ; |
|
4091 } |
|
4092 |
|
4093 void CEikDialogPageContainer::SetEditableL( TBool aEditable ) |
|
4094 { |
|
4095 iIsEditable=aEditable; |
|
4096 (*iPageArray)[iActivePage]->SetEditableL( aEditable, ETrue ) ; |
|
4097 (*iPageArray)[iActivePage]->UpdateScrollBarL(); |
|
4098 } |
|
4099 |
|
4100 CEikFormAnim* CEikDialogPageContainer::AcquireAnim( |
|
4101 TBool aAcquire, MEikFormAnimObserver* aObserver ) const |
|
4102 { |
|
4103 // You could add assertions here to make sure animation usage is exclusive |
|
4104 // (animation must be unacquired before anyone can acquire it). |
|
4105 // Unfortunately, CaptionedControl::SetCurrent usage is currently not |
|
4106 // exclusive. |
|
4107 if( iAnimation ) |
|
4108 { |
|
4109 if( aAcquire ) |
|
4110 { |
|
4111 iAnimation->SetObserver( aObserver ); |
|
4112 return iAnimation; |
|
4113 } |
|
4114 else // Unacquire |
|
4115 { |
|
4116 iAnimation->SetObserver( NULL ); |
|
4117 return NULL; |
|
4118 } |
|
4119 } |
|
4120 |
|
4121 return NULL; |
|
4122 } |
|
4123 |
|
4124 /** |
|
4125 * Writes the internal state of the control and its components to aStream. |
|
4126 * Does nothing in release mode. |
|
4127 * Designed to be overidden and base called by subclasses. |
|
4128 * |
|
4129 * @internal |
|
4130 * @since App-Framework_6.1 |
|
4131 */ |
|
4132 #ifndef _DEBUG |
|
4133 void CEikDialogPageContainer::WriteInternalStateL(RWriteStream&) const |
|
4134 {} |
|
4135 #else |
|
4136 void CEikDialogPageContainer::WriteInternalStateL(RWriteStream& aWriteStream) const |
|
4137 { |
|
4138 CCoeControl::WriteInternalStateL(aWriteStream); |
|
4139 } |
|
4140 #endif |
|
4141 |
|
4142 void CEikDialogPageContainer::HandleResourceChange(TInt aType) |
|
4143 { |
|
4144 // Animation is skin dependent, whenever skin changes animation changes |
|
4145 // too. |
|
4146 if( KAknsMessageSkinChange == aType ) |
|
4147 { |
|
4148 if( iAnimation ) |
|
4149 { |
|
4150 iAnimation->ReleaseAnimation(); |
|
4151 } |
|
4152 } |
|
4153 |
|
4154 CCoeControl::HandleResourceChange(aType); |
|
4155 |
|
4156 if(aType==KEikDynamicLayoutVariantSwitch) |
|
4157 { |
|
4158 SizeChanged(); |
|
4159 } |
|
4160 |
|
4161 TInt numPages = iPageArray->Count(); |
|
4162 for (TInt ii=0; ii<numPages; ii++) |
|
4163 { |
|
4164 if (ii != iActivePage) // active page already done by CCoeControl::HandleResourceChange() |
|
4165 (*iPageArray)[ii]->HandleResourceChange(aType); |
|
4166 } |
|
4167 } |
|
4168 |
|
4169 const CEikDialogPageSelector* CEikDialogPageContainer::PageSelector() const |
|
4170 { |
|
4171 return iPageSelector; |
|
4172 } |
|
4173 |
|
4174 void CEikDialogPageContainer::SetPageSelector(const CEikDialogPageSelector* aPageSelector) |
|
4175 { |
|
4176 iPageSelector = aPageSelector; |
|
4177 } |
|
4178 |
|
4179 void CEikDialogPageContainer::SetPageFormSized() |
|
4180 { |
|
4181 iForm = ETrue; |
|
4182 |
|
4183 // |
|
4184 // Form layout |
|
4185 // |
|
4186 |
|
4187 /** Dialog page container and page have the same size */ |
|
4188 TRect mainPaneRect; |
|
4189 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect ); |
|
4190 mainPaneRect = TRect( mainPaneRect.Size() ); // Moving to point (0, 0) |
|
4191 TAknLayoutRect formPaneLt; |
|
4192 formPaneLt.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine() ); |
|
4193 formPaneLt.LayoutRect( formPaneLt.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine() ); |
|
4194 |
|
4195 // |
|
4196 // End of form layout |
|
4197 // |
|
4198 |
|
4199 if ( formPaneLt.Rect() != Rect() ) |
|
4200 { |
|
4201 // TODO: use static method to do variation between traditional scrolling and panning when available |
|
4202 //SetRect( formPaneLt.Rect() ); |
|
4203 SetRect( mainPaneRect ); |
|
4204 } |
|
4205 |
|
4206 /** Only forms have line highlight animations. Animation creation is delayed |
|
4207 * here. |
|
4208 */ |
|
4209 if ( !iAnimation ) |
|
4210 { |
|
4211 TRAPD( err, iAnimation = CEikFormAnim::NewL() ); |
|
4212 |
|
4213 if ( KErrNone != err ) |
|
4214 { |
|
4215 iAnimation = NULL; |
|
4216 } |
|
4217 } |
|
4218 } |
|
4219 |
|
4220 CEikScrollBarFrame* CEikDialogPageContainer::ScrollBar() const |
|
4221 { |
|
4222 return iSBFrame; |
|
4223 } |
|
4224 |
|
4225 TBool CEikDialogPageContainer::HitRegionContains( const TPoint& /*aPoint*/, const CCoeControl& /*aControl*/ ) const |
|
4226 { |
|
4227 if ( iActivePage >= 0 ) |
|
4228 { |
|
4229 return !(*iPageArray)[iActivePage]->LineHandlerCalled(); |
|
4230 } |
|
4231 |
|
4232 return ETrue; |
|
4233 } |
|
4234 |