94 TRAP_IGNORE(const_cast<CEikCapCArray*>(this)->CreateExtensionL()); |
95 TRAP_IGNORE(const_cast<CEikCapCArray*>(this)->CreateExtensionL()); |
95 } |
96 } |
96 return iExtension; |
97 return iExtension; |
97 } |
98 } |
98 |
99 |
99 TInt CEikCapCArray::NumberOfTextLines() const |
100 |
100 { |
|
101 CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL; |
|
102 const CEikDialogPage *dialogPage = firstCapCC ? firstCapCC->DialogPage() : NULL; |
|
103 CEikDialogPage::TFormLayoutSelection ret = CEikDialogPage::ESingle; |
|
104 if ( dialogPage ) |
|
105 ret = dialogPage->FormLayout(); |
|
106 |
|
107 TInt lines = 0; |
|
108 for(TInt i = 0; i<Count(); i++) |
|
109 { |
|
110 TInt num_of_lines = 0; |
|
111 CEikCaptionedControl *line = (*this)[i]; |
|
112 if (ret == CEikDialogPage::ESingle) |
|
113 { |
|
114 //line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
115 TInt h = line->NumberOfLinesForScrollBar(); |
|
116 num_of_lines = h; |
|
117 } |
|
118 else if (ret == CEikDialogPage::EDouble) |
|
119 { |
|
120 //line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
121 TInt h = line->NumberOfLinesForScrollBar(); |
|
122 num_of_lines = h; // one for title |
|
123 } |
|
124 lines += num_of_lines; |
|
125 } |
|
126 return lines; |
|
127 } |
|
128 |
|
129 TInt CEikCapCArray::NumberOfTextLinesBeforeLine(TInt aLine) const |
|
130 { |
|
131 CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL; |
|
132 const CEikDialogPage *dialogPage = firstCapCC ? firstCapCC->DialogPage() : NULL; |
|
133 CEikDialogPage::TFormLayoutSelection ret = CEikDialogPage::ESingle; |
|
134 if ( dialogPage ) |
|
135 ret = dialogPage->FormLayout(); |
|
136 |
|
137 TInt lines = 0; |
|
138 for(TInt i = 0; i<aLine; i++) |
|
139 { |
|
140 TInt num_of_lines = 0; |
|
141 CEikCaptionedControl *line = (*this)[i]; |
|
142 if (ret == CEikDialogPage::ESingle) |
|
143 { |
|
144 //line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
145 TInt h = line->NumberOfLinesForScrollBar(); |
|
146 num_of_lines = h; |
|
147 } |
|
148 else if (ret == CEikDialogPage::EDouble) |
|
149 { |
|
150 //line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
151 TInt h = line->NumberOfLinesForScrollBar(); |
|
152 num_of_lines = h; // one for title |
|
153 } |
|
154 lines += num_of_lines; |
|
155 } |
|
156 return lines; |
|
157 |
|
158 } |
|
159 |
|
160 TInt CEikCapCArray::FindItemFromTextLine(TInt aTextLine) const |
|
161 { |
|
162 CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL; |
|
163 const CEikDialogPage *dialogPage = firstCapCC ? firstCapCC->DialogPage() : NULL; |
|
164 CEikDialogPage::TFormLayoutSelection ret = CEikDialogPage::ESingle; |
|
165 if ( dialogPage ) |
|
166 ret = dialogPage->FormLayout(); |
|
167 |
|
168 TInt lines = 0; |
|
169 TInt i = 0; |
|
170 for(i = 0; i<Count(); i++) |
|
171 { |
|
172 TInt num_of_lines = 0; |
|
173 CEikCaptionedControl *line = (*this)[i]; |
|
174 if (ret == CEikDialogPage::ESingle) |
|
175 { |
|
176 //line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
177 TInt h = line->NumberOfLinesForScrollBar(); |
|
178 num_of_lines = h; |
|
179 } |
|
180 else if (ret == CEikDialogPage::EDouble) |
|
181 { |
|
182 //line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
183 TInt h = line->NumberOfLinesForScrollBar(); |
|
184 num_of_lines = h; // one for title |
|
185 } |
|
186 lines += num_of_lines; |
|
187 if (lines > aTextLine) |
|
188 break; |
|
189 } |
|
190 return i; |
|
191 } |
|
192 /** |
101 /** |
193 * Calculate the size of all the component controls stacked vertically. |
102 * Calculate the size of all the component controls stacked vertically. |
194 * For Avkon Forms the controls overlap by 2 pixels (hard coded) |
103 * For Avkon Forms the controls overlap by 2 pixels (hard coded) |
195 */ |
104 */ |
196 EXPORT_C TSize CEikCapCArray::MinimumSize() |
105 EXPORT_C TSize CEikCapCArray::MinimumSize() |
197 { |
106 { |
|
107 _AKNTRACE_FUNC_ENTER; |
198 TSize size(0,0); |
108 TSize size(0,0); |
199 |
109 |
200 CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL; |
110 CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL; |
201 if (firstCapCC && firstCapCC->iIsFormControl) |
111 if (firstCapCC && firstCapCC->iIsFormControl) |
202 { // we're inside form |
112 { // we're inside form |
203 // Minimumsize needs to be called even though we wouldnt use the result (at least it calculates the number of lines) |
113 // Minimumsize needs to be called even though we wouldnt use the result (at least it calculates the number of lines) |
204 // TP HACK START (made because MinimumSize() is not good name for situations where content dimensions are desired) |
114 // TP HACK START (made because MinimumSize() is not good name for situations where content dimensions are desired) |
205 TInt height = 0; |
115 TInt height = 0; |
206 TInt width = 0; |
116 TInt width = 0; |
207 TRect parentRect = Rect(); |
|
208 TSize lineSize; // absolute size, minimumSize = maximumSize = LAF size |
117 TSize lineSize; // absolute size, minimumSize = maximumSize = LAF size |
209 for(TInt i=0;i<Count();i++) |
118 for(TInt i=0;i<Count();i++) |
210 { |
119 { |
211 TInt gap = 0; // not possible to get this from LAF. (should be 0.5u or something) |
|
212 CEikCaptionedControl *line = (*this)[i]; |
120 CEikCaptionedControl *line = (*this)[i]; |
213 TAknWindowLineLayout layout; |
121 lineSize = line->MinimumSize(); // ensures NumberOfLines() is valid. |
214 const CEikDialogPage *dialogPage = firstCapCC->DialogPage(); |
122 height += lineSize.iHeight; |
215 CEikDialogPage::TFormLayoutSelection ret = CEikDialogPage::ESingle; |
|
216 if ( dialogPage ) |
|
217 ret = dialogPage->FormLayout(); |
|
218 if (ret == CEikDialogPage::ESingle) |
|
219 { |
|
220 lineSize = line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
221 } |
|
222 else if (ret == CEikDialogPage::EDouble) |
|
223 { |
|
224 lineSize = line->MinimumSize(); // ensures NumberOfLines() is valid. |
|
225 } |
|
226 height += lineSize.iHeight + gap; |
|
227 width = lineSize.iWidth; |
123 width = lineSize.iWidth; |
228 } |
124 } |
229 size = TSize(width,height); |
125 size.SetSize(width,height); |
230 } |
126 } |
231 else |
127 else |
232 { |
128 { |
233 |
129 TInt wholeWidth=0; |
234 TInt wholeWidth=0; |
130 const TInt count=Count(); |
235 const TInt count=Count(); |
131 const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin; |
236 const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin; |
132 const TInt bottomMargin = iDensePacking ? KAknNoTopMargin : KAknTopMargin ; |
237 const TInt bottomMargin = iDensePacking ? KAknNoTopMargin : KAknTopMargin ; |
133 const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing; |
238 const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing; |
134 TInt deltaHeight=0; |
239 TInt deltaHeight=0; |
135 CEikCapCArrayExtension *extension = ExtensionOrNull(); |
240 CEikCapCArrayExtension *extension = ExtensionOrNull(); |
136 if (!extension) return TSize(30,30); // OOM |
241 if (!extension) return TSize(30,30); // OOM |
137 for (TInt ii=0;ii<count;++ii) |
242 for (TInt ii=0;ii<count;++ii) |
138 { |
243 { |
139 CEikCaptionedControl* line=(*this)[ii]; |
244 CEikCaptionedControl* line=(*this)[ii]; |
140 TSize thisSize=line->MinimumSize(); |
245 TSize thisSize=line->MinimumSize(); |
141 TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing; |
246 TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing; |
142 if (deltaHeight<thisDeltaHeight) |
247 if (deltaHeight<thisDeltaHeight) |
143 deltaHeight=thisDeltaHeight; |
248 deltaHeight=thisDeltaHeight; |
144 const TInt thisCaptionWidth=line->iCaptionWidth; |
249 const TInt thisCaptionWidth=line->iCaptionWidth; |
145 if (!(line->LatentGroupLineFollows())) |
250 if (!(line->LatentGroupLineFollows())) |
146 { |
251 { |
147 size.iHeight+=deltaHeight; |
252 size.iHeight+=deltaHeight; |
148 deltaHeight=0; |
253 deltaHeight=0; |
149 } |
254 } |
150 if (!thisCaptionWidth) |
255 if (!thisCaptionWidth) |
151 { |
256 { |
152 if (wholeWidth<thisSize.iWidth) |
257 if (wholeWidth<thisSize.iWidth) |
153 wholeWidth=thisSize.iWidth; |
258 wholeWidth=thisSize.iWidth; |
154 } |
259 } |
155 else |
260 else |
156 { |
261 { |
157 thisSize.iWidth-=thisCaptionWidth; |
262 thisSize.iWidth-=thisCaptionWidth; |
158 if (extension->iCaptionWidth<thisCaptionWidth) |
263 if (extension->iCaptionWidth<thisCaptionWidth) |
159 extension->iCaptionWidth=thisCaptionWidth; |
264 extension->iCaptionWidth=thisCaptionWidth; |
160 if (size.iWidth<thisSize.iWidth) |
265 if (size.iWidth<thisSize.iWidth) |
161 size.iWidth=thisSize.iWidth; |
266 size.iWidth=thisSize.iWidth; |
162 } |
267 } |
163 } |
268 } |
164 size.iWidth+=extension->iCaptionWidth; |
269 size.iWidth+=extension->iCaptionWidth; |
165 if (size.iWidth<wholeWidth) |
270 if (size.iWidth<wholeWidth) |
166 size.iWidth=wholeWidth; |
271 size.iWidth=wholeWidth; |
167 // If the total height is zero don't bother adding a top margin |
272 // If the total height is zero don't bother adding a top margin |
168 if ( size.iHeight > 0 ) |
273 if ( size.iHeight > 0 ) |
169 { |
274 { |
170 size.iHeight+=( topMargin + bottomMargin ) ; |
275 size.iHeight+=( topMargin + bottomMargin ) ; |
171 size.iHeight+=2 ; // (we have included one too many '-2's) |
276 size.iHeight+=2 ; // (we have included one too many '-2's) |
172 } |
277 } |
173 } |
278 } |
174 _AKNTRACE( "The Size : ( %d, %d ) ", size.iHeight, size.iWidth ); |
|
175 _AKNTRACE_FUNC_EXIT; |
279 return size; |
176 return size; |
280 } |
177 } |
281 |
178 |
282 |
179 |
283 /** |
180 /** |
464 EXPORT_C void CEikCapCArray::SetRect(const TRect &aRect) |
360 EXPORT_C void CEikCapCArray::SetRect(const TRect &aRect) |
465 { |
361 { |
466 SetRect(aRect, 0, -1, -1); |
362 SetRect(aRect, 0, -1, -1); |
467 } |
363 } |
468 |
364 |
469 /** |
|
470 * If aControl is an edwin, set its clipping rect to empty. This |
|
471 * will disable the text hiding. |
|
472 */ |
|
473 static void ResetHides(CEikCaptionedControl *aControl) |
|
474 { |
|
475 aControl->SetPartiallyVisible( EFalse ); |
|
476 if (aControl->ControlIsAnEdwin(aControl->iControlType)) |
|
477 { |
|
478 CEikEdwin *edwin = (CEikEdwin*)aControl->iControl; |
|
479 edwin->SetTextLinesRect(TRect()); |
|
480 } |
|
481 } |
|
482 |
|
483 /** |
|
484 * Sets a clipping rectangle for hiding the whole or a part of edwin's text. |
|
485 * |
|
486 * The reason for using this function is the multiline edwins. The text inside |
|
487 * an edwin can be broken to two or more lines, which must be hidden or shown |
|
488 * independently from each other. That is why it is not enough just to move |
|
489 * the whole edwin out of the screen. |
|
490 * |
|
491 * @param aClipRect The clipping rect for edwin's text. An empty rect disables |
|
492 * hiding. |
|
493 * |
|
494 * @return How many subcontrols were hidden |
|
495 */ |
|
496 static TInt HideLines_Edwin(CEikEdwin *aEdwin, TRect aClipRect) |
|
497 { |
|
498 aEdwin->SetTextLinesRect(aClipRect); |
|
499 |
|
500 // Create rects of the first and last edwin lines |
|
501 TPoint edwinTl( aEdwin->Rect().iTl ); |
|
502 TPoint edwinBr( aEdwin->Rect().iBr ); |
|
503 TRect textFirstLine; |
|
504 aEdwin->TextLayout()->GetLineRect(edwinTl.iY, textFirstLine); |
|
505 textFirstLine.Move( edwinTl.iX, edwinTl.iY + aEdwin->Margins().iTop ); |
|
506 TRect textLastLine; |
|
507 aEdwin->TextLayout()->GetLineRect(edwinBr.iY, textLastLine); |
|
508 textLastLine.Move( edwinBr.iX, edwinBr.iY - aEdwin->Margins().iTop - textLastLine.Height() ); |
|
509 |
|
510 // Check if at least one line fits to the clipping rect |
|
511 if( aClipRect.Contains(textFirstLine.iTl) && |
|
512 aClipRect.iBr.iY >= textFirstLine.iBr.iY ) // The first line fits |
|
513 return 0; |
|
514 if( aClipRect.Contains(textLastLine.iTl) && |
|
515 aClipRect.iBr.iY >= textLastLine.iBr.iY ) // The last line fits |
|
516 return 0; |
|
517 return 1; |
|
518 } |
|
519 |
|
520 /** |
|
521 * Tries to hide the specified control. The control will be hidden, if it doesn't |
|
522 * fit to the specified clipping rectangle. Checks if the control exists. |
|
523 * |
|
524 * @return How many subcontrols were hidden |
|
525 */ |
|
526 static TInt HideLines_Ctrl(CCoeControl *aControl, TRect aClipRect) |
|
527 { |
|
528 if ( !aControl ) |
|
529 return 1; // It doesn't exist and hence not visible |
|
530 TRect rect( aControl->Rect() ); |
|
531 if ( !aClipRect.Contains(rect.iTl) || aClipRect.iBr.iY <= rect.iBr.iY ) |
|
532 // Never use TRect::Contains() for checking the bottom right corner, see documentation |
|
533 { |
|
534 // hide it |
|
535 aControl->SetPosition( TPoint(-666,-666) ); |
|
536 return 1; |
|
537 } |
|
538 else |
|
539 return 0; |
|
540 } |
|
541 |
|
542 /** |
|
543 * Get vertically minimal rectangle of the two given. |
|
544 * |
|
545 * Vertically reduces aRect1 by aRect2's dangling part, if aRect2 |
|
546 * doesn't fit to aRect1. |
|
547 * |
|
548 * Sets aRect1 to the resulting minimal rectangle. |
|
549 */ |
|
550 static void GetVertMinRect( TRect& aRect1, const TRect aRect2 ) |
|
551 { |
|
552 // If aRect2's top doesn't fit, lower aRect1's top |
|
553 if( aRect2.iTl.iY < aRect1.iTl.iY ) |
|
554 aRect1.iTl.iY = Max( aRect1.iTl.iY, aRect2.iBr.iY ); |
|
555 // If aRect2's bottom doesn't fit, raise aRect1's bottom |
|
556 if( aRect2.iBr.iY > aRect1.iBr.iY ) |
|
557 aRect1.iBr.iY = Min( aRect1.iBr.iY, aRect2.iTl.iY ); |
|
558 } |
|
559 |
|
560 /** |
|
561 * Hides the specified form line, if it does not fit to the specified clipping rectangle. |
|
562 * The function never hides focused editable lines. If the form layout is single, the whole |
|
563 * captioned control is hidden. |
|
564 * |
|
565 * @param aControl The form line to be hidden |
|
566 * @param aClipRect The clipping rectangle |
|
567 * |
|
568 * @return How many subcontrols remained visible |
|
569 */ |
|
570 static TInt HideLines(CEikCaptionedControl *aControl, TRect aClipRect) |
|
571 { |
|
572 TInt visibleCtrls = 3; // Visible subcontrols after hiding |
|
573 CEikCaptionedControl *currentdLine = aControl->DialogPage()->CurrentLine(); |
|
574 if( ( aControl == currentdLine ) && aControl->iIsEditable ) |
|
575 { |
|
576 return visibleCtrls; |
|
577 } |
|
578 |
|
579 TBool isEdwin = aControl->ControlIsAnEdwin(aControl->iControlType); |
|
580 CEikEdwin* edwin( NULL ); |
|
581 if( isEdwin ) |
|
582 edwin = (CEikEdwin*)aControl->iControl; |
|
583 TRect ctrlRect( aControl->iControl->Rect() ); |
|
584 |
|
585 if( isEdwin ) |
|
586 { |
|
587 // Adjust rectangle only to the first line (with edwin's top margin) |
|
588 TRect textFirstLine; |
|
589 edwin->TextLayout()->GetLineRect(ctrlRect.iTl.iY, textFirstLine); |
|
590 ctrlRect.iBr.iY = ctrlRect.iTl.iY + edwin->Margins().iTop + textFirstLine.Height(); |
|
591 } |
|
592 |
|
593 // Find the minimal clipping rectangle |
|
594 if( aControl->iBitmap ) |
|
595 GetVertMinRect( aClipRect, aControl->iBitmap->Rect() ); |
|
596 if( aControl->iCaption ) |
|
597 GetVertMinRect( aClipRect, aControl->iCaption->Rect() ); |
|
598 GetVertMinRect( aClipRect, ctrlRect ); |
|
599 |
|
600 |
|
601 |
|
602 // Try to hide all controls on the current line |
|
603 aControl->SetPartiallyVisible( ETrue ); |
|
604 visibleCtrls -= HideLines_Ctrl( aControl->iBitmap, aClipRect ); |
|
605 visibleCtrls -= HideLines_Ctrl( aControl->iCaption, aClipRect ); |
|
606 if( isEdwin ) |
|
607 visibleCtrls -= HideLines_Edwin( edwin, aClipRect ); |
|
608 else |
|
609 visibleCtrls -= HideLines_Ctrl( aControl->iControl, aClipRect ); |
|
610 return visibleCtrls; |
|
611 } |
|
612 |
365 |
613 /** |
366 /** |
614 * Places the dialog items according to the current visible window position. |
367 * Places the dialog items according to the current visible window position. |
615 * When hiding items, uses SetExtent() instead of just SetPosition() in order to call |
368 * When hiding items, uses SetExtent() instead of just SetPosition() in order to call |
616 * SizeChanged() of the moved item. For example, this is needed for the editor to |
369 * SizeChanged() of the moved item. For example, this is needed for the editor to |
634 * corrected. Usually, @a aTop and @a aBottom come out of sync with the item sizes |
387 * corrected. Usually, @a aTop and @a aBottom come out of sync with the item sizes |
635 * after the dynamic layout change. |
388 * after the dynamic layout change. |
636 */ |
389 */ |
637 void CEikCapCArray::SetRect(const TRect& aRect, TInt aTop, TInt /*aMiddle*/, TInt aBottom) |
390 void CEikCapCArray::SetRect(const TRect& aRect, TInt aTop, TInt /*aMiddle*/, TInt aBottom) |
638 { |
391 { |
|
392 _AKNTRACE_FUNC_ENTER; |
639 TAknLayoutRect formtLayoutRect; |
393 TAknLayoutRect formtLayoutRect; |
640 formtLayoutRect.LayoutRect(aRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine()); |
394 formtLayoutRect.LayoutRect(aRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine()); |
641 formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine()); |
395 formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine()); |
642 TRect formRect = formtLayoutRect.Rect(); |
396 TRect formRect( formtLayoutRect.Rect() ); |
643 |
397 |
644 CEikCapCArrayExtension *extension_or_null = ExtensionOrNull(); |
398 CEikCapCArrayExtension *extension_or_null = ExtensionOrNull(); |
|
399 |
|
400 TBool rectChanged = ETrue; |
|
401 |
645 if (extension_or_null) |
402 if (extension_or_null) |
646 { |
403 { |
|
404 rectChanged = ( extension_or_null->iRect != formRect ); |
647 extension_or_null->iRect = formRect; |
405 extension_or_null->iRect = formRect; |
648 } |
406 } |
649 |
407 |
650 // controls need to be placed in real locations if physics is enabled |
408 // controls need to be placed in real locations if physics is enabled |
651 if ( Count() > 0 ) |
409 if ( Count() > 0 ) |
652 { |
410 { |
653 CEikCaptionedControl* control = (*this)[0]; |
411 CEikCaptionedControl* control = (*this)[0]; |
654 |
412 |
655 if ( control->DialogPage()->IsForm() ) |
413 if ( control->DialogPage()->IsForm() ) |
656 { |
414 { |
657 SetRealRect( aRect, aTop, aBottom ); |
415 if ( rectChanged ) |
|
416 { |
|
417 SetRealRect( aRect, aTop, aBottom ); |
|
418 } |
|
419 |
|
420 _AKNTRACE_FUNC_EXIT; |
658 return; |
421 return; |
659 } |
422 } |
660 } |
423 } |
661 |
424 |
662 TBool topDefined = EFalse; // top or bottom number defined? |
425 // rest of the function is executed for dialogs and empty forms only |
663 if( aTop > -1 ) |
426 TRect rect(aRect); |
664 { |
427 const TInt fullWidth=rect.iBr.iX-rect.iTl.iX; |
665 topDefined = ETrue; |
428 const TInt count=Count(); |
666 } |
429 const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin; |
667 else if( aBottom > -1 ) |
430 const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing; |
668 { |
431 rect.iTl.iY+=topMargin; |
669 topDefined = EFalse; |
432 TInt deltaHeight=0; |
670 } |
433 for (TInt ii=0;ii<count;++ii) |
671 else // aBottom == aTop == -1 |
434 { |
672 { |
435 CEikCaptionedControl* line=(*this)[ii]; |
673 User::Panic( _L("CEikCapCArray::SetRect(): Neither top nor bottom items number defined"), EAknPanicInvalidValue ); |
436 TSize thisSize=line->MinimumSize(); |
674 } |
437 TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing; |
675 const TInt count = Count(); |
438 if (deltaHeight<thisDeltaHeight) |
676 const TInt rectHeight = aRect.Height(); |
439 deltaHeight=thisDeltaHeight; |
677 /** |
440 if (!(line->iCaptionWidth)) |
678 * Special invisible points are used for placing the items that are |
441 thisSize.iWidth=fullWidth; |
679 * outside the window. CCoeControl's invisible flag cannot be used, |
442 else |
680 * as it is controlled by third-party applications. |
443 { |
681 */ |
444 CEikCapCArrayExtension *ext = ExtensionOrNull(); |
682 const TPoint topInvisPoint( -10000, -10000 ); |
445 TInt deltaWidth = 0; |
683 const TPoint bottomInvisPoint( 10000, 10000 ); |
446 |
684 |
447 if (ext) |
685 CEikCaptionedControl *firstCapCC = count > 0 ? (*this)[0] : NULL; |
448 deltaWidth = ext->iCaptionWidth-line->iCaptionWidth; |
686 if( firstCapCC && firstCapCC->iIsFormControl ) // Forms |
449 thisSize.iWidth+=deltaWidth; |
687 { |
450 if (ext) |
688 CEikCaptionedControl *selectedLine( NULL ); |
451 line->iCaptionWidth=ext->iCaptionWidth; |
689 if( firstCapCC->DialogPage()) |
452 else |
690 selectedLine = firstCapCC->DialogPage()->CurrentLine(); |
453 line->iCaptionWidth = 0; |
691 |
454 } |
692 // Check height of items and the input parameters aTop and aBottom. |
455 line->iFullWidth=fullWidth; |
693 TInt rest = 0; // number of the rest items without aTop or aBottom |
456 line->SetExtent(rect.iTl,thisSize); |
694 TInt index = 0; |
457 if (!(line->LatentGroupLineFollows())) |
695 if( topDefined ) |
458 { |
696 { |
459 rect.iTl.iY+=deltaHeight; |
697 rest = count - aTop; |
460 deltaHeight=0; |
698 index = aTop; |
461 } |
699 } |
462 } |
700 else |
463 |
701 { |
464 _AKNTRACE_FUNC_EXIT; |
702 rest = count - aBottom; |
|
703 index = rest - 1; |
|
704 } |
|
705 TInt height = 0; |
|
706 for( TInt ii = 0; ii < rest; ii++ ) |
|
707 { |
|
708 CEikCaptionedControl* line = (*this)[index]; |
|
709 height += line->MinimumSize().iHeight; // Use MinimumSize() here as a protection from dynamic layout change |
|
710 if( height >= rectHeight ) |
|
711 break; // Input params are OK |
|
712 topDefined? index++ : index--; |
|
713 } |
|
714 /** |
|
715 * If the window contains too few items inside and there are still items outside, |
|
716 * correct the input parameters @a aTop and @a aBottom to fill up the window. |
|
717 */ |
|
718 if( height < rectHeight ) |
|
719 { |
|
720 if( topDefined && aTop > 0 ) // For top-down placement and there are items above the window |
|
721 { |
|
722 // Calculate height of controls above the window also |
|
723 for( TInt ii = 0; ii < aTop; ii++ ) |
|
724 { |
|
725 CEikCaptionedControl* line = (*this)[ii]; |
|
726 height += line->MinimumSize().iHeight; |
|
727 if( height >= rectHeight ) // All items don't fit to the window anyway |
|
728 { |
|
729 topDefined = EFalse; // Reverse direction to bottom-up |
|
730 aBottom = 0; |
|
731 break; |
|
732 } |
|
733 } |
|
734 if( height < rectHeight ) // All items fit to the window |
|
735 { |
|
736 aTop = 0; // Just place them from the first item |
|
737 } |
|
738 } |
|
739 else if( !topDefined ) // For bottom-up placement |
|
740 { |
|
741 topDefined = ETrue; // Reverse direction to top-down |
|
742 aTop = 0; |
|
743 } |
|
744 } |
|
745 |
|
746 // Hiding items that are explicitly defined to be outside the window |
|
747 TInt start; |
|
748 TInt end; |
|
749 TPoint invisPoint; // current invisible point, depends on placement direction |
|
750 if( topDefined ) |
|
751 { |
|
752 start = 0; |
|
753 end = aTop; |
|
754 invisPoint = topInvisPoint; |
|
755 } |
|
756 else |
|
757 { |
|
758 start = count - aBottom; |
|
759 end = count; |
|
760 invisPoint = bottomInvisPoint; |
|
761 } |
|
762 for( TInt ii = start; ii < end; ii++ ) |
|
763 { |
|
764 CEikCaptionedControl* line = (*this)[ii]; |
|
765 line->SetPosition( invisPoint ); |
|
766 } |
|
767 |
|
768 // Setting rects for the rest of the items |
|
769 if( topDefined ) |
|
770 { |
|
771 rest = count - aTop; |
|
772 invisPoint = bottomInvisPoint; |
|
773 index = aTop; |
|
774 } |
|
775 else |
|
776 { |
|
777 rest = count - aBottom; |
|
778 invisPoint = topInvisPoint; |
|
779 index = rest - 1; |
|
780 } |
|
781 TInt reservedHeight = 0; // in pixels |
|
782 TBool insideWindow = ETrue; // The current item is still inside the window |
|
783 TInt topY = 0; |
|
784 |
|
785 |
|
786 for( TInt ii = 0; ii < rest; ii++ ) |
|
787 { |
|
788 CEikCaptionedControl* line = (*this)[index]; |
|
789 TSize lineSize( line->Size() ); |
|
790 if( insideWindow ) |
|
791 { |
|
792 ResetHides( line ); |
|
793 if( topDefined ) |
|
794 { // Top-down placement |
|
795 topY = aRect.iTl.iY + reservedHeight; |
|
796 } |
|
797 else |
|
798 { // Bottom-up placement |
|
799 topY = aRect.iBr.iY - reservedHeight - lineSize.iHeight; |
|
800 } |
|
801 line->SetExtent( TPoint( formRect.iTl.iX, topY ), lineSize ); |
|
802 AknsUtils::RegisterControlPosition( line ); |
|
803 AknsUtils::RegisterControlPosition( line->iCaption ); |
|
804 AknsUtils::RegisterControlPosition( line->iControl ); |
|
805 AknsUtils::RegisterControlPosition( line->iTrailer ); |
|
806 AknsUtils::RegisterControlPosition( line->iBitmap ); |
|
807 reservedHeight += lineSize.iHeight; |
|
808 /** |
|
809 * The control at a window edge is considered as partially-visible. |
|
810 * Its subcontrols must be checked for visibility individually. |
|
811 */ |
|
812 if( reservedHeight > rectHeight ) |
|
813 { |
|
814 TInt visibleSubctrls = HideLines( line, aRect ); // Check how many subcontrols stayed visible |
|
815 insideWindow = EFalse; |
|
816 /** |
|
817 * For the bottom-up placement: |
|
818 * if the window contains only an empty "partially-visible" control and a |
|
819 * a selected popup field, make the popup to hang at the top alone. |
|
820 */ |
|
821 if( !topDefined && index < count - 1 ) // bottom-up and not last |
|
822 { |
|
823 CEikCaptionedControl* lineBelow = (*this)[index+1]; |
|
824 if( visibleSubctrls == 0 && ii == 1 && |
|
825 IsPopupField( lineBelow ) && lineBelow == selectedLine ) |
|
826 { |
|
827 TRect popupRect( lineBelow->Rect() ); |
|
828 TInt diff = aRect.iTl.iY - popupRect.iTl.iY; // negative |
|
829 popupRect.Move( 0, diff ); |
|
830 lineBelow->SetRect( popupRect ); |
|
831 } |
|
832 } |
|
833 } |
|
834 } |
|
835 else |
|
836 { |
|
837 line->SetPosition( invisPoint ); |
|
838 } |
|
839 topDefined? index++ : index--; |
|
840 } |
|
841 } |
|
842 else // Dialogs other than forms: |
|
843 { |
|
844 TRect rect=aRect; |
|
845 const TInt fullWidth=rect.iBr.iX-rect.iTl.iX; |
|
846 const TInt count=Count(); |
|
847 const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin; |
|
848 const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing; |
|
849 rect.iTl.iY+=topMargin; |
|
850 TInt deltaHeight=0; |
|
851 for (TInt ii=0;ii<count;++ii) |
|
852 { |
|
853 CEikCaptionedControl* line=(*this)[ii]; |
|
854 TSize thisSize=line->MinimumSize(); |
|
855 TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing; |
|
856 if (deltaHeight<thisDeltaHeight) |
|
857 deltaHeight=thisDeltaHeight; |
|
858 if (!(line->iCaptionWidth)) |
|
859 thisSize.iWidth=fullWidth; |
|
860 else |
|
861 { |
|
862 CEikCapCArrayExtension *ext = ExtensionOrNull(); |
|
863 TInt deltaWidth = 0; |
|
864 if (ext) |
|
865 deltaWidth = ext->iCaptionWidth-line->iCaptionWidth; |
|
866 thisSize.iWidth+=deltaWidth; |
|
867 if (ext) |
|
868 line->iCaptionWidth=ext->iCaptionWidth; |
|
869 else |
|
870 line->iCaptionWidth = 0; |
|
871 line->iMinSize.iWidth+=deltaWidth; |
|
872 } |
|
873 line->iFullWidth=fullWidth; |
|
874 line->SetExtent(rect.iTl,thisSize); |
|
875 if (!(line->LatentGroupLineFollows())) |
|
876 { |
|
877 rect.iTl.iY+=deltaHeight; |
|
878 deltaHeight=0; |
|
879 } |
|
880 } |
|
881 } |
|
882 } |
|
883 |
|
884 TInt CEikCapCArray::YPosToLine(const TRect &aRect, |
|
885 TInt aTop, TInt aMiddle, TInt aBottom, |
|
886 TInt aYCoord) |
|
887 { |
|
888 TInt top = aTop; |
|
889 TInt middle = aMiddle; |
|
890 TInt bottom = aBottom; |
|
891 CalcItemIndexes(top, middle, bottom, aRect.Size()); |
|
892 |
|
893 for(int i = top ; i < top+middle; i++) |
|
894 { |
|
895 CEikCaptionedControl *fst = (*this)[i]; |
|
896 if (aYCoord < fst->Rect().iTl.iY) |
|
897 { |
|
898 if (i > 0) |
|
899 return i-1; |
|
900 else |
|
901 return KErrNotFound; |
|
902 } |
|
903 } |
|
904 if (Count() == 0) return -1; |
|
905 TInt ii = top+middle-1; |
|
906 CEikCaptionedControl *last = (*this)[ii]; |
|
907 if ( aYCoord < last->Rect().iBr.iY ) |
|
908 { |
|
909 return ii; |
|
910 } |
|
911 else |
|
912 { |
|
913 if ( ii+1 < Count() ) |
|
914 { |
|
915 return ii+1; |
|
916 } |
|
917 else if ( aYCoord > last->Rect().iBr.iY ) |
|
918 { |
|
919 return KErrNotFound; |
|
920 } |
|
921 else |
|
922 { |
|
923 return ii; |
|
924 } |
|
925 } |
|
926 } |
465 } |
927 |
466 |
928 EXPORT_C void CEikCapCArray::ResetMinimumSizes() |
467 EXPORT_C void CEikCapCArray::ResetMinimumSizes() |
929 { |
468 { |
930 const TInt count=Count(); |
469 const TInt count=Count(); |
966 ii++; |
505 ii++; |
967 } |
506 } |
968 return(KErrNotFound); |
507 return(KErrNotFound); |
969 } |
508 } |
970 |
509 |
971 // --------------------------------------------------------------------------- |
|
972 // CEikCapCArray::ScrollByPixels |
|
973 // --------------------------------------------------------------------------- |
|
974 // |
|
975 TInt CEikCapCArray::ScrollByPixels( TInt aDelta ) |
|
976 { |
|
977 TInt count = Count(); |
|
978 |
|
979 // Top and bottom of lines |
|
980 TInt topY = (*this)[0]->Rect().iTl.iY; |
|
981 TInt bottomY = (*this)[count - 1]->Rect().iBr.iY; |
|
982 |
|
983 TRect formRect( Rect() ); |
|
984 |
|
985 if ( aDelta ) |
|
986 { |
|
987 for( TInt i = 0; i < count; ++i ) |
|
988 { |
|
989 CEikCaptionedControl* line = (*this)[i]; |
|
990 TBool onDisplay = line->Rect().Intersects( formRect ); |
|
991 TPoint position( line->Position() ); |
|
992 position.iY += aDelta; |
|
993 |
|
994 line->SetPosition( position ); |
|
995 |
|
996 onDisplay = onDisplay || line->Rect().Intersects( formRect ); |
|
997 |
|
998 // Line is or was on display |
|
999 if ( ETrue /*onDisplay*/ ) |
|
1000 // Some controls, eg. slider and edwin don't handle |
|
1001 // SetPosition properly. Workaround is to use SetRect, |
|
1002 // which is slow as it does a whole layout for the control. |
|
1003 // If form panning is ever speed optimized, captioned |
|
1004 // control should me made to support SetPosition() correctly. |
|
1005 { |
|
1006 if ( line->ControlIsAPopfield( line->iControlType ) ) |
|
1007 { |
|
1008 // Have to layout whole captioned control, otherwise |
|
1009 // text doesn't move. Fix later popup field to move |
|
1010 // properly. |
|
1011 line->SetRect( line->Rect() ); |
|
1012 } |
|
1013 else |
|
1014 { |
|
1015 line->iControl->SetRect( line->iControl->Rect() ); |
|
1016 } |
|
1017 line->DrawDeferred(); |
|
1018 //line->DrawNow(); |
|
1019 } |
|
1020 } |
|
1021 } |
|
1022 |
|
1023 return aDelta; |
|
1024 } |
|
1025 |
510 |
1026 // --------------------------------------------------------------------------- |
511 // --------------------------------------------------------------------------- |
1027 // CEikCapCArray::SetRealRect |
512 // CEikCapCArray::SetRealRect |
1028 // --------------------------------------------------------------------------- |
513 // --------------------------------------------------------------------------- |
1029 // |
514 // |
1030 void CEikCapCArray::SetRealRect( |
515 void CEikCapCArray::SetRealRect( |
1031 const TRect& /*aRect*/, TInt /*aTop*/, TInt /*aBottom*/ ) |
516 const TRect& /*aRect*/, TInt /*aTop*/, TInt /*aBottom*/ ) |
1032 { |
517 { |
|
518 _AKNTRACE_FUNC_ENTER; |
1033 TInt count = Count(); |
519 TInt count = Count(); |
1034 const TPoint virtualTl( 1000, 0 ); |
520 const TPoint virtualTl( 1000, 0 ); |
1035 TPoint skinLocation( 0, 0 ); |
521 TPoint skinLocation( 0, 0 ); |
1036 CEikCaptionedControl* currentLine = (*this)[0]->DialogPage()->CurrentLine(); |
522 CEikCaptionedControl* currentLine = (*this)[0]->DialogPage()->CurrentLine(); |
1037 |
523 |
1107 // CEikCapCArray::MoveLineToScreen |
594 // CEikCapCArray::MoveLineToScreen |
1108 // --------------------------------------------------------------------------- |
595 // --------------------------------------------------------------------------- |
1109 // |
596 // |
1110 void CEikCapCArray::MoveLineToScreen( TInt aLine, TInt aTopY, TBool aVisible ) |
597 void CEikCapCArray::MoveLineToScreen( TInt aLine, TInt aTopY, TBool aVisible ) |
1111 { |
598 { |
|
599 _AKNTRACE_FUNC_ENTER; |
|
600 _AKNTRACE( "aLine: [%d], aTopY: [%d], aVisible: [%d]", aLine, aTopY, aVisible ); |
1112 if ( aLine != -1 && aLine < Count() ) |
601 if ( aLine != -1 && aLine < Count() ) |
1113 { |
602 { |
1114 CEikCaptionedControl* line = (*this)[aLine]; |
603 CEikCaptionedControl* line = (*this)[aLine]; |
1115 TPoint topLeft( 1000, 0 ); |
604 TPoint topLeft( 1000, 0 ); |
1116 |
605 |
1117 if ( aVisible ) |
606 if ( aVisible ) |
1118 { |
607 { |
1119 topLeft.SetXY( Rect().iTl.iX, LineIndexToYPosition( aLine, aTopY ) ); |
608 topLeft.SetXY( Rect().iTl.iX, LineIndexToYPosition( aLine, aTopY ) ); |
1120 } |
609 } |
1121 |
610 |
1122 line->SetRect( TRect( topLeft, line->Size() ) ); |
611 TRect newRect( topLeft, line->Size() ); |
1123 } |
612 |
|
613 if ( newRect != line->Rect() ) |
|
614 { |
|
615 line->SetRect( TRect( topLeft, line->Size() ) ); |
|
616 } |
|
617 } |
|
618 _AKNTRACE_FUNC_EXIT; |
1124 } |
619 } |
1125 |
620 |
1126 |
621 |
1127 // --------------------------------------------------------------------------- |
622 // --------------------------------------------------------------------------- |
1128 // CEikCapCArray::FocusableLine |
623 // CEikCapCArray::FocusableLine |
1129 // --------------------------------------------------------------------------- |
624 // --------------------------------------------------------------------------- |
1130 // |
625 // |
1131 TInt CEikCapCArray::FocusableLine( TInt aCurrentLine, TInt aTopY ) |
626 TInt CEikCapCArray::FocusableLine( TInt aCurrentLine, TInt aTopY ) |
1132 { |
627 { |
|
628 _AKNTRACE_FUNC_ENTER; |
|
629 _AKNTRACE( "aCurrentLine: [%d]", aCurrentLine ); |
1133 TInt focusableLine = KErrNotFound; |
630 TInt focusableLine = KErrNotFound; |
1134 |
631 |
1135 if ( aCurrentLine >= 0 && aCurrentLine < Count() ) |
632 if ( aCurrentLine >= 0 && aCurrentLine < Count() ) |
1136 { |
633 { |
1137 TInt y = LineIndexToYPosition( aCurrentLine, aTopY ); |
634 TInt y = LineIndexToYPosition( aCurrentLine, aTopY ); |
1138 |
635 |
1139 // if current line is visible on the screen the focus that |
636 // if current line is visible on the screen then focus that |
1140 if ( y >= 0 && y <= Rect().Height() ) |
637 if ( y >= 0 && y <= Rect().Height() ) |
1141 { |
638 { |
1142 focusableLine = aCurrentLine; |
639 focusableLine = aCurrentLine; |
1143 } |
640 } |
1144 else // otherwise return the topmost totally visible line |
641 else // otherwise return the topmost totally visible line |