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