uifw/EikStd/dlgsrc/EIKCAPCA.CPP
branchRCL_3
changeset 55 aecbbf00d063
parent 50 a1caeb42b3a3
child 56 d48ab3b357f1
equal deleted inserted replaced
51:fcdfafb36fe7 55:aecbbf00d063
    22 #include <AknUtils.h>
    22 #include <AknUtils.h>
    23 #include <aknlayoutscalable_avkon.cdl.h>
    23 #include <aknlayoutscalable_avkon.cdl.h>
    24 #include <AknsUtils.h>
    24 #include <AknsUtils.h>
    25 #include <eikedwin.h>
    25 #include <eikedwin.h>
    26 #include "AknPanic.h"
    26 #include "AknPanic.h"
    27 #include "akntrace.h"
       
    28 
    27 
    29 const TInt KVerticalSpacing=-2;  // Avkon form controls overlap by two pixels!
    28 const TInt KVerticalSpacing=-2;  // Avkon form controls overlap by two pixels!
    30 const TInt KVerticalSpacingSquash=0;
    29 const TInt KVerticalSpacingSquash=0;
    31 
    30 
    32 const TInt KAknTopMargin = 0 ;
    31 const TInt KAknTopMargin = 0 ;
    95 		TRAP_IGNORE(const_cast<CEikCapCArray*>(this)->CreateExtensionL());
    94 		TRAP_IGNORE(const_cast<CEikCapCArray*>(this)->CreateExtensionL());
    96 		}
    95 		}
    97 	return iExtension;
    96 	return iExtension;
    98 }
    97 }
    99 
    98 
   100 
    99 TInt CEikCapCArray::NumberOfTextLines() const
       
   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 	}
   101 /**
   192 /**
   102  *  Calculate the size of all the component controls stacked vertically.
   193  *  Calculate the size of all the component controls stacked vertically.
   103  *  For Avkon Forms the controls overlap by 2 pixels (hard coded)
   194  *  For Avkon Forms the controls overlap by 2 pixels (hard coded)
   104  */
   195  */
   105 EXPORT_C TSize CEikCapCArray::MinimumSize()
   196 EXPORT_C TSize CEikCapCArray::MinimumSize()
   106 	{
   197 	{
   107 	_AKNTRACE_FUNC_ENTER;
       
   108 	TSize size(0,0);
   198 	TSize size(0,0);
   109 
   199 
   110 	CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL;
   200 	CEikCaptionedControl *firstCapCC = Count() > 0 ? (*this)[0] : NULL;
   111 	if (firstCapCC && firstCapCC->iIsFormControl)
   201 	if (firstCapCC && firstCapCC->iIsFormControl)
   112 		{ // we're inside form
   202 		{ // we're inside form
   113 	    // Minimumsize needs to be called even though we wouldnt use the result (at least it calculates the number of lines)
   203 	    // Minimumsize needs to be called even though we wouldnt use the result (at least it calculates the number of lines)
   114 		// TP HACK START (made because MinimumSize() is not good name for situations where content dimensions are desired)
   204 		// TP HACK START (made because MinimumSize() is not good name for situations where content dimensions are desired)
   115 		TInt height = 0;
   205 		TInt height = 0;
   116 		TInt width = 0;
   206 		TInt width = 0;
       
   207 		TRect parentRect = Rect();
   117 		TSize lineSize; // absolute size, minimumSize = maximumSize = LAF size
   208 		TSize lineSize; // absolute size, minimumSize = maximumSize = LAF size
   118 		for(TInt i=0;i<Count();i++)
   209 		for(TInt i=0;i<Count();i++)
   119 			{
   210 			{
       
   211 			TInt gap = 0; // not possible to get this from LAF. (should be 0.5u or something)
   120 			CEikCaptionedControl *line = (*this)[i];
   212 			CEikCaptionedControl *line = (*this)[i];
   121             lineSize = line->MinimumSize(); // ensures NumberOfLines() is valid.
   213 				TAknWindowLineLayout layout;
   122 			height += lineSize.iHeight;
   214 			const CEikDialogPage *dialogPage = firstCapCC->DialogPage();
       
   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;
   123 			width = lineSize.iWidth;
   227 			width = lineSize.iWidth;
   124 			}
   228 			}
   125 		size.SetSize(width,height);
   229 		size = TSize(width,height);
   126 		}
   230 		}
   127 	else
   231 	else
   128 		{
   232 		{
   129         TInt wholeWidth=0;
   233 
   130         const TInt count=Count();
   234 	TInt wholeWidth=0;
   131         const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin;
   235 	const TInt count=Count();
   132         const TInt bottomMargin = iDensePacking ? KAknNoTopMargin : KAknTopMargin ;
   236 	const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin;
   133         const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing;
   237 	const TInt bottomMargin = iDensePacking ? KAknNoTopMargin : KAknTopMargin ;
   134         TInt deltaHeight=0;
   238 	const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing;
   135         CEikCapCArrayExtension *extension = ExtensionOrNull();
   239 	TInt deltaHeight=0;
   136         if (!extension) return TSize(30,30); // OOM
   240 	CEikCapCArrayExtension *extension = ExtensionOrNull();
   137         for (TInt ii=0;ii<count;++ii)
   241 	if (!extension) return TSize(30,30); // OOM
   138             {
   242 	for (TInt ii=0;ii<count;++ii)
   139             CEikCaptionedControl* line=(*this)[ii];
   243 		{
   140             TSize thisSize=line->MinimumSize();
   244 		CEikCaptionedControl* line=(*this)[ii];
   141             TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing;
   245 		TSize thisSize=line->MinimumSize();
   142             if (deltaHeight<thisDeltaHeight)
   246 		TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing;
   143                 deltaHeight=thisDeltaHeight;
   247 		if (deltaHeight<thisDeltaHeight)
   144             const TInt thisCaptionWidth=line->iCaptionWidth;
   248 			deltaHeight=thisDeltaHeight;
   145             if (!(line->LatentGroupLineFollows()))
   249 		const TInt thisCaptionWidth=line->iCaptionWidth;
   146                 {
   250 		if (!(line->LatentGroupLineFollows()))
   147                 size.iHeight+=deltaHeight;
   251 			{
   148                 deltaHeight=0;
   252 			size.iHeight+=deltaHeight;
   149                 }
   253 			deltaHeight=0;
   150             if (!thisCaptionWidth)
   254 			}
   151                 {
   255 		if (!thisCaptionWidth)
   152                 if (wholeWidth<thisSize.iWidth)
   256 			{
   153                     wholeWidth=thisSize.iWidth;
   257 			if (wholeWidth<thisSize.iWidth)
   154                 }
   258 				wholeWidth=thisSize.iWidth;
   155             else
   259 			}
   156                 {
   260 		else
   157                 thisSize.iWidth-=thisCaptionWidth;
   261 			{
   158                 if (extension->iCaptionWidth<thisCaptionWidth)
   262 			thisSize.iWidth-=thisCaptionWidth;
   159                     extension->iCaptionWidth=thisCaptionWidth;
   263 			if (extension->iCaptionWidth<thisCaptionWidth)
   160                 if (size.iWidth<thisSize.iWidth)
   264 				extension->iCaptionWidth=thisCaptionWidth;
   161                     size.iWidth=thisSize.iWidth;
   265 			if (size.iWidth<thisSize.iWidth)
   162                 }
   266 				size.iWidth=thisSize.iWidth;
   163             }
   267 			}
   164         size.iWidth+=extension->iCaptionWidth;
   268 		}
   165         if (size.iWidth<wholeWidth)
   269 	size.iWidth+=extension->iCaptionWidth;
   166             size.iWidth=wholeWidth;
   270 	if (size.iWidth<wholeWidth)
   167         // If the total height is zero don't bother adding a top margin
   271 		size.iWidth=wholeWidth;
   168         if ( size.iHeight > 0 )
   272 	// If the total height is zero don't bother adding a top margin
   169             {
   273 	if ( size.iHeight > 0 )
   170             size.iHeight+=( topMargin + bottomMargin ) ;
   274 		{
   171             size.iHeight+=2 ;  // (we have included one too many '-2's)
   275 		size.iHeight+=( topMargin + bottomMargin ) ;
   172             }
   276 		size.iHeight+=2 ;  // (we have included one too many '-2's)
   173         }
   277 		}
   174     _AKNTRACE( "The Size : ( %d, %d ) ", size.iHeight, size.iWidth );
   278 	}
   175 	_AKNTRACE_FUNC_EXIT;
       
   176 	return size;
   279 	return size;
   177 	}
   280 	}
   178 
   281 
   179 
   282 
   180 /**
   283 /**
   258 			}	
   361 			}	
   259 		else
   362 		else
   260 			{
   363 			{
   261 			// should Panic() here 
   364 			// should Panic() here 
   262 			}
   365 			}
   263 		TRect rect(aAreaSize);
   366 		TRect rect = TRect(TPoint(0,0), aAreaSize);
   264 		TAknLayoutRect layoutRect;
   367 		TAknLayoutRect layoutRect;
   265 		layoutRect.LayoutRect(rect, layout);
   368 		layoutRect.LayoutRect(rect, layout);
   266 		TInt height2 = layoutRect.Rect().Height();
   369 		TInt height2 = layoutRect.Rect().Height();
   267 		reservedHeight += height2;
   370 		reservedHeight += height2;
   268 
   371 
   269 		if (reservedHeight > aAreaSize.iHeight)
   372 		if (reservedHeight > aAreaSize.iHeight)
   270 			{
   373 			{
   271 			break;
   374 			break;
   272 			}
   375 			}
       
   376 
   273 
   377 
   274 		newMiddle = i + 1;
   378 		newMiddle = i + 1;
   275 		if (aTopItemIndex == -1)
   379 		if (aTopItemIndex == -1)
   276 			{
   380 			{
   277 			newTop = count - i - 1 - aBottomItemIndex;
   381 			newTop = count - i - 1 - aBottomItemIndex;
   360 EXPORT_C void CEikCapCArray::SetRect(const TRect &aRect)
   464 EXPORT_C void CEikCapCArray::SetRect(const TRect &aRect)
   361 {
   465 {
   362 	SetRect(aRect, 0, -1, -1);
   466 	SetRect(aRect, 0, -1, -1);
   363 }
   467 }
   364 
   468 
       
   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 	}
   365 
   612 
   366 /**
   613 /**
   367 * Places the dialog items according to the current visible window position.
   614 * Places the dialog items according to the current visible window position.
   368 * When hiding items, uses SetExtent() instead of just SetPosition() in order to call
   615 * When hiding items, uses SetExtent() instead of just SetPosition() in order to call
   369 * SizeChanged() of the moved item. For example, this is needed for the editor to
   616 * SizeChanged() of the moved item. For example, this is needed for the editor to
   387 * corrected. Usually, @a aTop and @a aBottom come out of sync with the item sizes
   634 * corrected. Usually, @a aTop and @a aBottom come out of sync with the item sizes
   388 * after the dynamic layout change.
   635 * after the dynamic layout change.
   389 */
   636 */
   390 void CEikCapCArray::SetRect(const TRect& aRect, TInt aTop, TInt /*aMiddle*/, TInt aBottom)
   637 void CEikCapCArray::SetRect(const TRect& aRect, TInt aTop, TInt /*aMiddle*/, TInt aBottom)
   391 	{
   638 	{
   392 	_AKNTRACE_FUNC_ENTER;
       
   393     TAknLayoutRect formtLayoutRect;
   639     TAknLayoutRect formtLayoutRect;
   394     formtLayoutRect.LayoutRect(aRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine());
   640     formtLayoutRect.LayoutRect(aRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine());
   395     formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine());
   641     formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine());
   396     TRect formRect( formtLayoutRect.Rect() );
   642     TRect formRect = formtLayoutRect.Rect();
   397 	
   643 	
   398 	CEikCapCArrayExtension *extension_or_null = ExtensionOrNull();
   644 	CEikCapCArrayExtension *extension_or_null = ExtensionOrNull();
   399 	
       
   400 	TBool rectChanged = ETrue;
       
   401 	
       
   402 	if (extension_or_null)
   645 	if (extension_or_null)
   403 		{
   646 		{
   404         rectChanged = ( extension_or_null->iRect != formRect );
       
   405 		extension_or_null->iRect = formRect;
   647 		extension_or_null->iRect = formRect;
   406 		}
   648 		}
   407 
   649 
   408     // controls need to be placed in real locations if physics is enabled
   650     // controls need to be placed in real locations if physics is enabled
   409     if ( Count() > 0 )
   651     if ( Count() > 0 )
   410         {
   652         {
   411         CEikCaptionedControl* control = (*this)[0];
   653         CEikCaptionedControl* control = (*this)[0];
   412         
   654         
   413         if ( control->DialogPage()->IsForm() )
   655         if ( control->DialogPage()->IsForm() )
   414             {
   656             {
   415             if ( rectChanged )
   657             SetRealRect( aRect, aTop, aBottom );
   416                 {
       
   417                 SetRealRect( aRect, aTop, aBottom );
       
   418                 }
       
   419 
       
   420             _AKNTRACE_FUNC_EXIT;
       
   421             return;
   658             return;
   422             }
   659             }
   423         }
   660         }
   424         
   661         
   425 	// rest of the function is executed for dialogs and empty forms only
   662 	TBool topDefined = EFalse;   // top or bottom number defined?
   426     TRect rect(aRect);
   663 	if( aTop > -1 )
   427     const TInt fullWidth=rect.iBr.iX-rect.iTl.iX;
   664 	    {
   428     const TInt count=Count();
   665 	    topDefined = ETrue;
   429     const TInt topMargin=iDensePacking ? KAknNoTopMargin : KAknTopMargin;
   666 	    }
   430     const TInt verticalSpacing=iDensePacking ? KVerticalSpacingSquash : KVerticalSpacing;
   667 	else if( aBottom > -1 )
   431     rect.iTl.iY+=topMargin;
   668 	    {
   432     TInt deltaHeight=0;
   669 	    topDefined = EFalse;
   433     for (TInt ii=0;ii<count;++ii)
   670 	    }
   434         {
   671 	else    // aBottom == aTop == -1
   435         CEikCaptionedControl* line=(*this)[ii];
   672 	    {
   436         TSize thisSize=line->MinimumSize();
   673 	    User::Panic( _L("CEikCapCArray::SetRect(): Neither top nor bottom items number defined"), EAknPanicInvalidValue );
   437         TInt thisDeltaHeight=thisSize.iHeight+verticalSpacing;
   674 	    }
   438         if (deltaHeight<thisDeltaHeight)
   675 	const TInt count = Count();
   439             deltaHeight=thisDeltaHeight;
   676 	const TInt rectHeight = aRect.Height();
   440         if (!(line->iCaptionWidth))
   677 	/**
   441             thisSize.iWidth=fullWidth;
   678 	* Special invisible points are used for placing the items that are
   442         else
   679 	* outside the window. CCoeControl's invisible flag cannot be used,
   443             {
   680 	* as it is controlled by third-party applications.
   444             CEikCapCArrayExtension *ext = ExtensionOrNull();
   681 	*/
   445             TInt deltaWidth = 0;
   682 	const TPoint topInvisPoint( -10000, -10000 );
   446 
   683 	const TPoint bottomInvisPoint( 10000, 10000 );
   447             if (ext) 
   684 	
   448                 deltaWidth = ext->iCaptionWidth-line->iCaptionWidth;
   685 	CEikCaptionedControl *firstCapCC = count > 0 ? (*this)[0] : NULL;
   449             thisSize.iWidth+=deltaWidth;
   686 	if( firstCapCC && firstCapCC->iIsFormControl )  // Forms
   450             if (ext)
   687 		{
   451                 line->iCaptionWidth=ext->iCaptionWidth;
   688 		CEikCaptionedControl *selectedLine( NULL );
   452             else
   689 		if( firstCapCC->DialogPage())
   453                 line->iCaptionWidth = 0;
   690 	        selectedLine = firstCapCC->DialogPage()->CurrentLine();
   454             }
   691 		
   455         line->iFullWidth=fullWidth;
   692 		// Check height of items and the input parameters aTop and aBottom.
   456         line->SetExtent(rect.iTl,thisSize);
   693 		TInt rest = 0;  // number of the rest items without aTop or aBottom
   457         if (!(line->LatentGroupLineFollows()))
   694 		TInt index = 0;
   458             {
   695     	if( topDefined )
   459             rect.iTl.iY+=deltaHeight;
   696     	    {
   460             deltaHeight=0;
   697     	    rest = count - aTop;
   461             }
   698     	    index = aTop;
   462         }
   699     	    }
   463 
   700     	else
   464     _AKNTRACE_FUNC_EXIT;
   701     	    {
       
   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 		}
   465 	}
   926 	}
   466 	
   927 	
   467 EXPORT_C void CEikCapCArray::ResetMinimumSizes()
   928 EXPORT_C void CEikCapCArray::ResetMinimumSizes()
   468 	{
   929 	{
   469 	const TInt count=Count();
   930 	const TInt count=Count();
   505 		ii++;
   966 		ii++;
   506 		}
   967 		}
   507 	return(KErrNotFound);
   968 	return(KErrNotFound);
   508 	}
   969 	}
   509 
   970 
       
   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     }
   510 
  1025 
   511 // ---------------------------------------------------------------------------
  1026 // ---------------------------------------------------------------------------
   512 // CEikCapCArray::SetRealRect
  1027 // CEikCapCArray::SetRealRect
   513 // ---------------------------------------------------------------------------
  1028 // ---------------------------------------------------------------------------
   514 //
  1029 //
   515 void CEikCapCArray::SetRealRect( 
  1030 void CEikCapCArray::SetRealRect( 
   516 		const TRect& /*aRect*/, TInt /*aTop*/, TInt /*aBottom*/ )
  1031 		const TRect& /*aRect*/, TInt /*aTop*/, TInt /*aBottom*/ )
   517     {
  1032     {
   518 	_AKNTRACE_FUNC_ENTER;
       
   519     TInt count = Count();
  1033     TInt count = Count();
   520     const TPoint virtualTl( 1000, 0 );
  1034     const TPoint virtualTl( 1000, 0 );
   521     TPoint skinLocation( 0, 0 );
  1035     TPoint skinLocation( 0, 0 );
   522     CEikCaptionedControl* currentLine = (*this)[0]->DialogPage()->CurrentLine();
  1036     CEikCaptionedControl* currentLine = (*this)[0]->DialogPage()->CurrentLine();
   523     
  1037     
   540         AknsUtils::RegisterControlPosition( line->iCaption, skinLocation );
  1054         AknsUtils::RegisterControlPosition( line->iCaption, skinLocation );
   541         AknsUtils::RegisterControlPosition( line->iControl, skinLocation );
  1055         AknsUtils::RegisterControlPosition( line->iControl, skinLocation );
   542         AknsUtils::RegisterControlPosition( line->iTrailer, skinLocation );
  1056         AknsUtils::RegisterControlPosition( line->iTrailer, skinLocation );
   543         AknsUtils::RegisterControlPosition( line->iBitmap, skinLocation );
  1057         AknsUtils::RegisterControlPosition( line->iBitmap, skinLocation );
   544         }
  1058         }
   545     _AKNTRACE_FUNC_EXIT;
       
   546     }
  1059     }
   547 
  1060 
   548 
  1061 
   549 // ---------------------------------------------------------------------------
  1062 // ---------------------------------------------------------------------------
   550 // CEikCapCArray::YPositionToLineIndex
  1063 // CEikCapCArray::YPositionToLineIndex
   594 // CEikCapCArray::MoveLineToScreen
  1107 // CEikCapCArray::MoveLineToScreen
   595 // ---------------------------------------------------------------------------
  1108 // ---------------------------------------------------------------------------
   596 //
  1109 //
   597 void CEikCapCArray::MoveLineToScreen( TInt aLine, TInt aTopY, TBool aVisible )
  1110 void CEikCapCArray::MoveLineToScreen( TInt aLine, TInt aTopY, TBool aVisible )
   598     {
  1111     {
   599 	_AKNTRACE_FUNC_ENTER;
       
   600 	_AKNTRACE( "aLine: [%d], aTopY: [%d], aVisible: [%d]", aLine, aTopY, aVisible );
       
   601     if ( aLine != -1 && aLine < Count() )
  1112     if ( aLine != -1 && aLine < Count() )
   602         {
  1113         {
   603         CEikCaptionedControl* line = (*this)[aLine];
  1114         CEikCaptionedControl* line = (*this)[aLine];
   604         TPoint topLeft( 1000, 0 );
  1115         TPoint topLeft( 1000, 0 );
   605         
  1116         
   606         if ( aVisible )
  1117         if ( aVisible )
   607             {
  1118             {
   608             topLeft.SetXY( Rect().iTl.iX, LineIndexToYPosition( aLine, aTopY ) );
  1119             topLeft.SetXY( Rect().iTl.iX, LineIndexToYPosition( aLine, aTopY ) );
   609             }
  1120             }
   610         
  1121         
   611         TRect newRect( topLeft, line->Size() );
  1122         line->SetRect( TRect( topLeft, line->Size() ) );
   612         
       
   613         if ( newRect != line->Rect() )
       
   614             {
       
   615             line->SetRect( TRect( topLeft, line->Size() ) );
       
   616             }
       
   617         }
  1123         }
   618     _AKNTRACE_FUNC_EXIT;
       
   619     }
  1124     }
   620 
  1125 
   621 
  1126 
   622 // ---------------------------------------------------------------------------
  1127 // ---------------------------------------------------------------------------
   623 // CEikCapCArray::FocusableLine
  1128 // CEikCapCArray::FocusableLine
   624 // ---------------------------------------------------------------------------
  1129 // ---------------------------------------------------------------------------
   625 //
  1130 //
   626 TInt CEikCapCArray::FocusableLine( TInt aCurrentLine, TInt aTopY )
  1131 TInt CEikCapCArray::FocusableLine( TInt aCurrentLine, TInt aTopY )
   627     {
  1132     {
   628 	_AKNTRACE_FUNC_ENTER;
       
   629 	_AKNTRACE( "aCurrentLine: [%d]", aCurrentLine );
       
   630     TInt focusableLine = KErrNotFound;
  1133     TInt focusableLine = KErrNotFound;
   631     
  1134     
   632     if ( aCurrentLine >= 0 && aCurrentLine < Count() )
  1135     if ( aCurrentLine >= 0 && aCurrentLine < Count() )
   633         {
  1136         {
   634         TInt y = LineIndexToYPosition( aCurrentLine, aTopY );
  1137         TInt y = LineIndexToYPosition( aCurrentLine, aTopY );
   635 
  1138 
   636         // if current line is visible on the screen then focus that
  1139         // if current line is visible on the screen the focus that
   637         if ( y >= 0 && y <= Rect().Height() )
  1140         if ( y >= 0 && y <= Rect().Height() )
   638             {
  1141             {
   639             focusableLine = aCurrentLine;
  1142             focusableLine = aCurrentLine;
   640             }
  1143             }
   641         else // otherwise return the topmost totally visible line
  1144         else // otherwise return the topmost totally visible line
   652                 
  1155                 
   653                 focusableLine = topLine;
  1156                 focusableLine = topLine;
   654                 }
  1157                 }
   655             }
  1158             }
   656         }
  1159         }
   657     _AKNTRACE_FUNC_EXIT;
  1160     
   658     return focusableLine;
  1161     return focusableLine;
   659     }
  1162     }
   660 
  1163