uifw/EikStd/dlgsrc/EIKCAPCA.CPP
branchRCL_3
changeset 50 a1caeb42b3a3
parent 29 a8834a2e9a96
child 55 aecbbf00d063
equal deleted inserted replaced
38:c52421ed5f07 50:a1caeb42b3a3
    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 
   371 			}	
   258 			}	
   372 		else
   259 		else
   373 			{
   260 			{
   374 			// should Panic() here 
   261 			// should Panic() here 
   375 			}
   262 			}
   376 		TRect rect = TRect(TPoint(0,0), aAreaSize);
   263 		TRect rect(aAreaSize);
   377 		TAknLayoutRect layoutRect;
   264 		TAknLayoutRect layoutRect;
   378 		layoutRect.LayoutRect(rect, layout);
   265 		layoutRect.LayoutRect(rect, layout);
   379 		TInt height2 = layoutRect.Rect().Height();
   266 		TInt height2 = layoutRect.Rect().Height();
   380 		reservedHeight += height2;
   267 		reservedHeight += height2;
   381 
   268 
   382 		if (reservedHeight > aAreaSize.iHeight)
   269 		if (reservedHeight > aAreaSize.iHeight)
   383 			{
   270 			{
   384 			break;
   271 			break;
   385 			}
   272 			}
   386 
       
   387 
   273 
   388 		newMiddle = i + 1;
   274 		newMiddle = i + 1;
   389 		if (aTopItemIndex == -1)
   275 		if (aTopItemIndex == -1)
   390 			{
   276 			{
   391 			newTop = count - i - 1 - aBottomItemIndex;
   277 			newTop = count - i - 1 - aBottomItemIndex;
   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
   648 	{
   391 	{
   649 	_AKNTRACE_FUNC_ENTER;
   392 	_AKNTRACE_FUNC_ENTER;
   650     TAknLayoutRect formtLayoutRect;
   393     TAknLayoutRect formtLayoutRect;
   651     formtLayoutRect.LayoutRect(aRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine());
   394     formtLayoutRect.LayoutRect(aRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine());
   652     formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine());
   395     formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine());
   653     TRect formRect = formtLayoutRect.Rect();
   396     TRect formRect( formtLayoutRect.Rect() );
   654 	
   397 	
   655 	CEikCapCArrayExtension *extension_or_null = ExtensionOrNull();
   398 	CEikCapCArrayExtension *extension_or_null = ExtensionOrNull();
   656 	
   399 	
   657 	TBool rectChanged = ETrue;
   400 	TBool rectChanged = ETrue;
   658 	
   401 	
   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 //
  1168     
   631     
  1169     if ( aCurrentLine >= 0 && aCurrentLine < Count() )
   632     if ( aCurrentLine >= 0 && aCurrentLine < Count() )
  1170         {
   633         {
  1171         TInt y = LineIndexToYPosition( aCurrentLine, aTopY );
   634         TInt y = LineIndexToYPosition( aCurrentLine, aTopY );
  1172 
   635 
  1173         // if current line is visible on the screen the focus that
   636         // if current line is visible on the screen then focus that
  1174         if ( y >= 0 && y <= Rect().Height() )
   637         if ( y >= 0 && y <= Rect().Height() )
  1175             {
   638             {
  1176             focusableLine = aCurrentLine;
   639             focusableLine = aCurrentLine;
  1177             }
   640             }
  1178         else // otherwise return the topmost totally visible line
   641         else // otherwise return the topmost totally visible line