uiacceltk/hitchcock/coretoolkit/src/HuiGridLayout.cpp
changeset 0 15bf7259bb7c
child 18 1801340c26a2
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   ?Description
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "uiacceltk/HuiGridLayout.h"  // Class definition
       
    21 #include "uiacceltk/HuiControl.h"
       
    22 #include "uiacceltk/HuiPanic.h"
       
    23 #include "uiacceltk/HuiUtil.h"
       
    24 #include "uiacceltk/huimetric.h"
       
    25 
       
    26 #include <AknUtils.h>
       
    27 
       
    28 
       
    29 #define FLOOR(x) (TReal32(TInt(TReal32(x))))
       
    30 #define FLOOR_INT(x) (TInt((x)))
       
    31 
       
    32 // Symbian does not have a native ceil() implementation, we need to use "near enough" rounding.
       
    33 #define CEIL(x) (TReal32(TInt(TReal32(x)+0.999f)))
       
    34 #define CEIL_INT(x) (TInt(TReal32(x)+0.999f))
       
    35 
       
    36 // Fractional part of real
       
    37 #define FRAC(x) (TReal32(x)-FLOOR(x))
       
    38 
       
    39 //
       
    40 // Private structures
       
    41 //
       
    42 
       
    43 struct TAxis
       
    44     {
       
    45     
       
    46     /** Array of block weights. Used to calculate relative sizes of lines of blocks. */
       
    47     RArray<THuiMetric> iWeights;
       
    48     TUint iLayoutFlags;    
       
    49     };
       
    50 
       
    51 /*
       
    52  * grid weights
       
    53  */
       
    54 struct CHuiGridLayout::TGridLayoutPrivateData
       
    55     {
       
    56 public:
       
    57     TGridLayoutPrivateData();
       
    58 public:
       
    59     RArray<TAxis> iAxes;
       
    60     
       
    61     /** Sets the grid dimensions to automatically expand to store more content */
       
    62     TInt iExpansionFlags;
       
    63     };
       
    64 
       
    65 CHuiGridLayout::TGridLayoutPrivateData::TGridLayoutPrivateData()
       
    66     : 
       
    67     iExpansionFlags(0) 
       
    68     {
       
    69     
       
    70     }
       
    71 
       
    72 
       
    73 //
       
    74 // class CHuiGridLayout
       
    75 //
       
    76 
       
    77 EXPORT_C CHuiGridLayout* CHuiGridLayout::AddNewL(CHuiControl& aOwnerControl, 
       
    78                                                  TInt aColumns, TInt aRows,
       
    79                                                  CHuiLayout* aParentLayout)
       
    80     {
       
    81     CHuiGridLayout* grid = STATIC_CAST(CHuiGridLayout*,
       
    82         aOwnerControl.AppendLayoutL(EHuiLayoutTypeGrid, aParentLayout));
       
    83     grid->SetColumnsL(aColumns);
       
    84     grid->SetRowsL(aRows);
       
    85 
       
    86     return grid;
       
    87     }
       
    88 
       
    89 
       
    90 EXPORT_C CHuiGridLayout::CHuiGridLayout(MHuiVisualOwner& aOwner)
       
    91         : CHuiLayout(aOwner)
       
    92     {
       
    93     }
       
    94 
       
    95 
       
    96 EXPORT_C void CHuiGridLayout::ConstructL()
       
    97     {    
       
    98     CHuiLayout::ConstructL();
       
    99     iGridLayoutData = new(ELeave) TGridLayoutPrivateData;
       
   100     for(TInt ii = EHuiGridColumn; ii <= EHuiGridRow; ii++)
       
   101         {
       
   102         TAxis axis;
       
   103         axis.iLayoutFlags = 0;
       
   104         
       
   105         iGridLayoutData->iAxes.AppendL(axis);
       
   106         }
       
   107     SetColumnsL(1);
       
   108     SetRowsL(1);
       
   109     }
       
   110 
       
   111 	
       
   112 EXPORT_C CHuiGridLayout::~CHuiGridLayout()
       
   113     {    
       
   114     if ( iGridLayoutData )
       
   115         {
       
   116         for(TInt ii = EHuiGridColumn; ii <= EHuiGridRow; ii++)
       
   117             {
       
   118             TAxis& axis = iGridLayoutData->iAxes[ii];
       
   119             axis.iWeights.Reset();
       
   120             }
       
   121 
       
   122         iGridLayoutData->iAxes.Reset();
       
   123         }
       
   124 
       
   125     delete iGridLayoutData;
       
   126     iGridLayoutData = 0;
       
   127     }
       
   128 
       
   129 
       
   130 EXPORT_C TInt CHuiGridLayout::ChildOrdinal(TInt aIndex)
       
   131     {
       
   132     // Use the visual index as ordinal.
       
   133     return EffectiveLayoutOrdinal(Visual(aIndex));
       
   134     }
       
   135 
       
   136 
       
   137 EXPORT_C TPoint CHuiGridLayout::OrdinalToBlock(TInt aOrdinal) const
       
   138     {
       
   139     TPoint block(0,0);
       
   140     TInt cols = ColumnCount();
       
   141     TInt rows = RowCount();
       
   142     
       
   143     if (cols && rows)
       
   144         {
       
   145         if ( iGridLayoutData->iExpansionFlags & EExpandHorizontally )
       
   146             {
       
   147             block.iX = aOrdinal / rows;
       
   148             block.iY = aOrdinal % rows;
       
   149             }
       
   150         else
       
   151             {
       
   152             // By default the flow is vertically
       
   153             block.iX = aOrdinal % cols;
       
   154             block.iY = aOrdinal / cols;
       
   155             }
       
   156         }
       
   157         
       
   158     return block;    
       
   159     }
       
   160 
       
   161 EXPORT_C void CHuiGridLayout::SetSize(const THuiRealSize& aSize, TInt aTransitionTime)
       
   162     {
       
   163     CHuiLayout::SetSize(aSize, aTransitionTime);
       
   164     UpdateChildrenLayout(aTransitionTime);    
       
   165     }
       
   166 
       
   167 EXPORT_C TBool CHuiGridLayout::ChildSize(TInt aOrdinal, TSize& aSize)
       
   168     {
       
   169     TBool result(EFalse);
       
   170     THuiRealRect rect;
       
   171     TInt childRectStatus(THuiLayoutChildRectUpdateNotNeeded);
       
   172     childRectStatus = ChildRect(aOrdinal, rect);
       
   173     if(childRectStatus != THuiLayoutChildRectNotImplemented)
       
   174         {
       
   175         result = (childRectStatus & THuiLayoutChildRectSizeUpdateNeeded);
       
   176         if(result)
       
   177             {
       
   178             THuiRealPoint size(rect.Width(), rect.Height());
       
   179             aSize = LocalPointInPixels(size).AsSize();
       
   180             }
       
   181         }
       
   182     return result;
       
   183     }
       
   184     
       
   185 EXPORT_C TBool CHuiGridLayout::ChildPos(TInt aOrdinal, TPoint& aPos)
       
   186     {
       
   187     TBool result(EFalse);
       
   188     THuiRealRect rect;
       
   189     TInt childRectStatus(THuiLayoutChildRectUpdateNotNeeded);
       
   190     childRectStatus = ChildRect(aOrdinal, rect);
       
   191     if(childRectStatus != THuiLayoutChildRectNotImplemented)
       
   192         {
       
   193         result = (childRectStatus & THuiLayoutChildRectPosUpdateNeeded);
       
   194         if(result)
       
   195             {
       
   196             aPos = LocalPointInPixels(rect.iTl);
       
   197             }
       
   198         }
       
   199     return result;
       
   200     }
       
   201     
       
   202     
       
   203 EXPORT_C TInt CHuiGridLayout::ChildRect(TInt aOrdinal, THuiRealRect& aPos)
       
   204     {        
       
   205     if (!ColumnCount() || !RowCount())
       
   206         {
       
   207         return THuiLayoutChildRectUpdateNotNeeded;
       
   208         }
       
   209         
       
   210     // @todo refactorize with CHuiLayout::InnerSize
       
   211     THuiRealRect paddingPx = PaddingInPixels(EHuiReferenceStateTarget);
       
   212 
       
   213     // find the inner border and remove the inner paddings
       
   214     THuiRealPoint innerSizePx = LocalPointInPixels(Size().RealTarget(), EHuiReferenceStateTarget);
       
   215     innerSizePx.iX -= paddingPx.iTl.iX + paddingPx.iBr.iX;
       
   216     innerSizePx.iY -= paddingPx.iTl.iY + paddingPx.iBr.iY;
       
   217 
       
   218     // subtract the inner padding (space between each child).
       
   219     THuiRealPoint innerPaddingPx = MetricToPixels(InnerPadding(), EHuiReferenceStateTarget);
       
   220      
       
   221     THuiRealPoint availablePx(innerSizePx.iX - ((ColumnCount() - 1) * innerPaddingPx.iX),
       
   222                               innerSizePx.iY - ((RowCount() - 1) * innerPaddingPx.iY));
       
   223 
       
   224     TPoint blockLogical = OrdinalToBlock(aOrdinal);
       
   225     TPoint blockPosPx;
       
   226     TSize blockSizePx;
       
   227 
       
   228     CalculateCellInPixels(EHuiGridColumn, blockLogical.iX, availablePx.iX, blockPosPx.iX, blockSizePx.iWidth);
       
   229     CalculateCellInPixels(EHuiGridRow, blockLogical.iY, availablePx.iY, blockPosPx.iY, blockSizePx.iHeight);    
       
   230 
       
   231     // now add back in the inner paddings and the padding
       
   232     blockPosPx.iX += HUI_ROUND_FLOAT_TO_INT( paddingPx.iTl.iX + (blockLogical.iX * innerPaddingPx.iX) );
       
   233     blockPosPx.iY += HUI_ROUND_FLOAT_TO_INT( paddingPx.iTl.iY + (blockLogical.iY * innerPaddingPx.iY) );
       
   234 
       
   235     // get metric reference, for converting between base units of this layout (from the child visual's perspective) and pixels
       
   236     THuiRealPoint layoutRefPx = MetricReferenceForLayoutInPixels(BaseUnit().Abs()); // always target reference
       
   237 
       
   238     // Convert the result back into child relative coordinates
       
   239     THuiXYMetric blockPosChildMetric = BaseUnit();
       
   240     THuiXYMetric blockSizeChildMetric = BaseUnit();
       
   241 
       
   242     ConvertPixelsToMetricLength(blockPosChildMetric.iX, TReal32(blockPosPx.iX), layoutRefPx.iX);
       
   243     ConvertPixelsToMetricLength(blockPosChildMetric.iY, TReal32(blockPosPx.iY), layoutRefPx.iY);
       
   244     ConvertPixelsToMetricLength(blockSizeChildMetric.iX, TReal32(blockSizePx.iWidth), layoutRefPx.iX);
       
   245     ConvertPixelsToMetricLength(blockSizeChildMetric.iY, TReal32(blockSizePx.iHeight), layoutRefPx.iY);
       
   246 
       
   247     aPos.iTl.iX =  blockPosChildMetric.iX.iMagnitude;
       
   248     aPos.iTl.iY =  blockPosChildMetric.iY.iMagnitude;
       
   249     aPos.iBr.iX = aPos.iTl.iX + blockSizeChildMetric.iX.iMagnitude;
       
   250     aPos.iBr.iY = aPos.iTl.iY + blockSizeChildMetric.iY.iMagnitude;
       
   251     
       
   252     return THuiLayoutChildRectLayoutUpdateNeeded;
       
   253     }
       
   254    
       
   255    
       
   256 EXPORT_C void CHuiGridLayout::SetColumnsL(TInt aColumnCount)
       
   257     {
       
   258     THuiMetric defaultWeight(1.f, EHuiUnitWeight);
       
   259     FillWeightsL(EHuiGridColumn, aColumnCount, defaultWeight);    
       
   260     }
       
   261    
       
   262     
       
   263 EXPORT_C void CHuiGridLayout::SetRowsL(TInt aRowCount)
       
   264     {
       
   265     THuiMetric defaultWeight(1.f, EHuiUnitWeight);
       
   266     FillWeightsL(EHuiGridRow, aRowCount, defaultWeight);    
       
   267     }
       
   268    
       
   269 
       
   270 EXPORT_C void CHuiGridLayout::SetColumnsL(const RArray<TInt>& aWeights)
       
   271     {
       
   272     TAxis& axis = iGridLayoutData->iAxes[EHuiGridColumn];
       
   273     axis.iWeights.Reset();
       
   274     for(TInt i = 0; i < aWeights.Count(); ++i)
       
   275         {
       
   276         THuiMetric weight(TReal32(aWeights[i]), EHuiUnitWeight);
       
   277         User::LeaveIfError(axis.iWeights.Append(weight));
       
   278         }
       
   279     }
       
   280     
       
   281 EXPORT_C void CHuiGridLayout::SetRowsL(const RArray<TInt>& aWeights)
       
   282     {
       
   283     TAxis& axis = iGridLayoutData->iAxes[EHuiGridRow];
       
   284     axis.iWeights.Reset();
       
   285     for(TInt i = 0; i < aWeights.Count(); ++i)
       
   286         {
       
   287         THuiMetric weight(TReal32(aWeights[i]), EHuiUnitWeight);
       
   288         User::LeaveIfError(axis.iWeights.Append(weight));
       
   289         }
       
   290     }
       
   291 
       
   292 EXPORT_C void CHuiGridLayout::FillWeightsL(THuiGridDimension aDim, TInt aCount, const THuiMetric& aWeight)
       
   293     {
       
   294     if(aDim <= EHuiGridRow)
       
   295         {
       
   296         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   297         axis.iWeights.Reset();
       
   298         for(TInt i = 0; i < aCount; ++i)
       
   299             {
       
   300             User::LeaveIfError(axis.iWeights.Append(aWeight));
       
   301             }
       
   302         }
       
   303     }
       
   304     
       
   305 EXPORT_C void CHuiGridLayout::AppendWeightL(THuiGridDimension aDim, const THuiMetric& aWeight)
       
   306     {
       
   307     if(aDim <= EHuiGridRow)
       
   308         {
       
   309         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   310         User::LeaveIfError(axis.iWeights.Append(aWeight));
       
   311         }
       
   312     }
       
   313     
       
   314 EXPORT_C void CHuiGridLayout::InsertWeightL(THuiGridDimension aDim, const THuiMetric& aWeight, TInt aPos)
       
   315     {
       
   316     if(aDim <= EHuiGridRow)
       
   317         {
       
   318         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   319         if(aPos < 0 || aPos >= axis.iWeights.Count())
       
   320             {
       
   321             User::Leave(KErrArgument);
       
   322             }
       
   323         else
       
   324             {
       
   325             User::LeaveIfError(axis.iWeights.Insert(aWeight, aPos));
       
   326             }
       
   327         }
       
   328     }
       
   329     
       
   330 EXPORT_C void CHuiGridLayout::ReplaceWeightL(THuiGridDimension aDim, const THuiMetric& aWeight, TInt aPos)
       
   331     {
       
   332     if(aDim <= EHuiGridRow)
       
   333         {
       
   334         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   335         if(aPos < 0 || aPos >= axis.iWeights.Count())
       
   336             {
       
   337             User::Leave(KErrArgument);
       
   338             }
       
   339         else
       
   340             {
       
   341             axis.iWeights[aPos] = aWeight;
       
   342             }
       
   343         }
       
   344     }
       
   345     
       
   346 EXPORT_C void CHuiGridLayout::RemoveWeightL(THuiGridDimension aDim, TInt aPos)
       
   347     {
       
   348     if(aDim <= EHuiGridRow)
       
   349         {
       
   350         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   351         if(aPos < 0 || aPos >= axis.iWeights.Count())
       
   352             {
       
   353             User::Leave(KErrArgument);
       
   354             }
       
   355         else
       
   356             {
       
   357             axis.iWeights.Remove(aPos);
       
   358             }
       
   359         }
       
   360     }
       
   361     
       
   362 EXPORT_C THuiMetric CHuiGridLayout::Weight(THuiGridDimension aDim, TInt aPos) const
       
   363     {
       
   364     THuiMetric metric(0.f, EHuiUnitWeight); 
       
   365     if(aDim <= EHuiGridRow)
       
   366         {
       
   367         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   368         if(aPos < 0 || aPos >= axis.iWeights.Count())
       
   369             {
       
   370             // use empty weight
       
   371             }
       
   372         else
       
   373             {
       
   374             metric = axis.iWeights[aPos];
       
   375             }
       
   376         }
       
   377     return metric;
       
   378     }
       
   379     
       
   380 EXPORT_C TInt CHuiGridLayout::DimensionCount(THuiGridDimension aDim) const
       
   381     {
       
   382     TInt count = 0;
       
   383     if(aDim <= EHuiGridRow)
       
   384         {
       
   385         count = iGridLayoutData->iAxes[aDim].iWeights.Count();
       
   386         }
       
   387     return count;
       
   388     }
       
   389 
       
   390 EXPORT_C void CHuiGridLayout::SetExpanding(TInt aFlags)
       
   391     {
       
   392     iGridLayoutData->iExpansionFlags = aFlags;    
       
   393     }
       
   394     
       
   395 // ---------------------------------------------------------------------------
       
   396 // Function that determines if the filling order.
       
   397 // ---------------------------------------------------------------------------
       
   398 //
       
   399 TBool CHuiGridLayout::UseRightToLeftFillingOrder() const
       
   400     {
       
   401     return CHuiStatic::LayoutMirrored();
       
   402     }
       
   403 
       
   404 EXPORT_C void CHuiGridLayout::GetClassName(TDes& aName) const
       
   405     {
       
   406     aName = _L("CHuiGridLayout");
       
   407     }
       
   408 
       
   409 EXPORT_C THuiXYMetric CHuiGridLayout::BaseUnit() const
       
   410     {
       
   411     return CHuiLayout::BaseUnit();
       
   412     }
       
   413 
       
   414 EXPORT_C CHuiVisual* CHuiGridLayout::FindTag(const TDesC8& aTag)
       
   415     {
       
   416     return CHuiLayout::FindTag(aTag);
       
   417     }
       
   418     
       
   419 EXPORT_C TInt CHuiGridLayout::Count() const
       
   420     {
       
   421     return CHuiLayout::Count();
       
   422     }
       
   423     
       
   424 EXPORT_C CHuiVisual& CHuiGridLayout::Visual(TInt aIndex) const
       
   425     {
       
   426     return CHuiLayout::Visual(aIndex);
       
   427     }
       
   428     
       
   429 EXPORT_C void CHuiGridLayout::SetPos(const THuiRealPoint& aPos, TInt aTransitionTime)
       
   430     {
       
   431     CHuiLayout::SetPos(aPos, aTransitionTime);
       
   432     }
       
   433     
       
   434 EXPORT_C void CHuiGridLayout::UpdateChildrenLayout(TInt aTransitionTime)
       
   435     {
       
   436     CHuiLayout::UpdateChildrenLayout(aTransitionTime);
       
   437     }
       
   438     
       
   439 EXPORT_C TBool CHuiGridLayout::PrepareDrawL()
       
   440     {
       
   441     return CHuiLayout::PrepareDrawL();
       
   442     }
       
   443     
       
   444 EXPORT_C void CHuiGridLayout::Draw(CHuiGc& aGc) const
       
   445     {
       
   446     CHuiLayout::Draw(aGc);
       
   447     }
       
   448     
       
   449 EXPORT_C void CHuiGridLayout::DrawSelf(CHuiGc& aGc, const TRect& aDisplayRect) const
       
   450     {
       
   451     CHuiLayout::DrawSelf(aGc, aDisplayRect);
       
   452     }
       
   453     
       
   454 EXPORT_C TBool CHuiGridLayout::Changed() const
       
   455     {
       
   456     return CHuiLayout::Changed();
       
   457     }
       
   458     
       
   459 EXPORT_C void CHuiGridLayout::ReportChanged()
       
   460     {
       
   461     CHuiLayout::ReportChanged();
       
   462     }
       
   463     
       
   464 EXPORT_C void CHuiGridLayout::ClearChanged()
       
   465     {
       
   466     CHuiLayout::ClearChanged();
       
   467     }
       
   468     
       
   469 EXPORT_C void CHuiGridLayout::NotifySkinChangedL()
       
   470     {
       
   471     CHuiLayout::NotifySkinChangedL();
       
   472     }
       
   473     
       
   474 EXPORT_C void CHuiGridLayout::ExpandRectWithContent(TRect& aRect) const
       
   475     {
       
   476     CHuiLayout::ExpandRectWithContent(aRect); 
       
   477     }
       
   478     
       
   479 EXPORT_C void CHuiGridLayout::VisualExtension(const TUid& aExtensionUid, TAny** aExtensionParams)
       
   480     {
       
   481     CHuiLayout::VisualExtension(aExtensionUid, aExtensionParams);
       
   482     }
       
   483     
       
   484 EXPORT_C void CHuiGridLayout::DumpTree() const
       
   485     {
       
   486     CHuiLayout::DumpTree();
       
   487     }
       
   488     
       
   489 EXPORT_C void CHuiGridLayout::GetInstanceName(TDes& aName) const
       
   490     {
       
   491     CHuiLayout::GetInstanceName(aName);
       
   492     }
       
   493 
       
   494 EXPORT_C void CHuiGridLayout::RemoveAndDestroyAllD()
       
   495     {
       
   496     CHuiLayout::RemoveAndDestroyAllD();
       
   497     }
       
   498 
       
   499 HUI_SESSION_OBJECT_IMPL_EXPORT(CHuiGridLayout, ETypeVisual)
       
   500 
       
   501 
       
   502 EXPORT_C TInt CHuiGridLayout::RowCount() const
       
   503     {
       
   504     return iGridLayoutData->iAxes[EHuiGridRow].iWeights.Count();
       
   505     }
       
   506 
       
   507 EXPORT_C TInt CHuiGridLayout::ColumnCount() const
       
   508     {
       
   509     return iGridLayoutData->iAxes[EHuiGridColumn].iWeights.Count();
       
   510     }
       
   511 
       
   512    
       
   513 EXPORT_C void CHuiGridLayout::SetLayoutModeFlags(THuiGridDimension aDim, TUint aGridLayoutModeFlags)
       
   514     {
       
   515     if(aDim <= EHuiGridRow)
       
   516         {
       
   517         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   518         TUint oldFlags = axis.iLayoutFlags;
       
   519         
       
   520 
       
   521         // The following flags are mutually exclusive, clear existing flags first
       
   522         if (aGridLayoutModeFlags&EHuiGridIncreaseInnerPadding)
       
   523             {
       
   524             axis.iLayoutFlags &= ~EHuiGridDecreaseInnerPadding;
       
   525             }
       
   526         
       
   527         if (aGridLayoutModeFlags&EHuiGridDecreaseInnerPadding)
       
   528             {
       
   529             axis.iLayoutFlags &= ~EHuiGridIncreaseInnerPadding;
       
   530             }        
       
   531 
       
   532         if (aGridLayoutModeFlags&EHuiGridIncreaseOuterPadding)
       
   533             {
       
   534             axis.iLayoutFlags &= ~EHuiGridDecreaseOuterPadding;
       
   535             }
       
   536         
       
   537         if (aGridLayoutModeFlags&EHuiGridDecreaseOuterPadding)
       
   538             {
       
   539             axis.iLayoutFlags &= ~EHuiGridIncreaseOuterPadding;
       
   540             }   
       
   541         
       
   542         axis.iLayoutFlags |= aGridLayoutModeFlags;
       
   543         
       
   544         if((oldFlags != axis.iLayoutFlags) && !(Flags() & EHuiVisualFlagFreezeLayout))
       
   545             {
       
   546             UpdateChildrenLayout(0);
       
   547             }          
       
   548         }             
       
   549     }
       
   550   
       
   551 EXPORT_C void CHuiGridLayout::ClearLayoutModeFlags(THuiGridDimension aDim, TUint aGridLayoutModeFlags)
       
   552     {
       
   553     if(aDim <= EHuiGridRow)
       
   554         {
       
   555         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   556         TUint oldFlags = axis.iLayoutFlags;      
       
   557         axis.iLayoutFlags &= ~aGridLayoutModeFlags;
       
   558         
       
   559         if((oldFlags != axis.iLayoutFlags) && !(Flags() & EHuiVisualFlagFreezeLayout))
       
   560             {
       
   561             UpdateChildrenLayout(0);
       
   562             }                         
       
   563         }          
       
   564     }
       
   565 
       
   566 EXPORT_C TUint CHuiGridLayout::LayoutModeFlags(THuiGridDimension aDim)
       
   567     {
       
   568     if(aDim <= EHuiGridRow)
       
   569         {
       
   570         TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   571         return axis.iLayoutFlags;
       
   572         }
       
   573         
       
   574     return 0;
       
   575     }
       
   576 
       
   577 void CHuiGridLayout::CalculateCellInPixels(
       
   578     THuiGridDimension aDim, 
       
   579     TInt aIndex, 
       
   580     TReal32 aAvailablePixels, 
       
   581     TInt& aPos, 
       
   582     TInt& aSize) const
       
   583     {
       
   584     ASSERT(aDim < EHuiGridSize);
       
   585     
       
   586     TAxis& axis = iGridLayoutData->iAxes[aDim]; 
       
   587     TInt numItems = (aDim==EHuiGridColumn)?ColumnCount():RowCount();    
       
   588     TInt itemIntegerWidths = 0;
       
   589     TInt itemCeilingedIntegerWidths = 0;
       
   590     TReal32 realPos;
       
   591     TReal32 realSize;
       
   592     TInt sumIntegerWidths;            
       
   593     TInt sumCeilingIntegerWidths;
       
   594     TReal32 layoutWidthPx;
       
   595     TReal32 layoutSizePx;    
       
   596             
       
   597     CalculateCellInPixelsReal(aDim, aIndex, aAvailablePixels, realPos, realSize, itemIntegerWidths, itemCeilingedIntegerWidths);
       
   598     
       
   599     TReal32 innerPadPos = realPos;
       
   600     
       
   601     // Decide what to do with pixel error based on flags
       
   602     if (axis.iLayoutFlags&EHuiGridDecreaseInnerPadding)
       
   603         {
       
   604         // Allow every item to grow out into the padding, this will make the padding appear smaller.
       
   605         realSize = CEIL(realSize);             
       
   606         }
       
   607     else if (axis.iLayoutFlags&EHuiGridIncreaseInnerPadding)
       
   608         {
       
   609         // Allow every item to be floored, this will make the padding appear bigger.
       
   610         realSize = FLOOR(realSize);             
       
   611         }
       
   612     else
       
   613         {
       
   614         // For PC-lint
       
   615         }
       
   616 
       
   617     if (axis.iLayoutFlags&EHuiGridIncreaseOuterPadding)            
       
   618         {
       
   619         // Ignore accumulated error, simply increase outer padding by the total error for the entire layout.
       
   620         
       
   621         // Ignore the rounded positions we have calculated, we get the pos by summing the integer widths,
       
   622         realPos = itemIntegerWidths-FLOOR_INT(realSize);
       
   623         
       
   624         CalculateCellInPixelsReal(aDim, numItems-1, aAvailablePixels, layoutWidthPx, layoutSizePx, sumIntegerWidths, sumCeilingIntegerWidths);            
       
   625         realPos += (aAvailablePixels-sumIntegerWidths)/2;
       
   626         realSize = FLOOR(realSize);
       
   627         }
       
   628     else if (axis.iLayoutFlags&EHuiGridDecreaseOuterPadding)
       
   629         {
       
   630         // Ignore accumulated error, simply decrease outer padding by the total error for the entire layout.
       
   631         
       
   632         // Ignore the rounded positions we have calculated, we get the pos by summing the integer widths,
       
   633         realPos = itemCeilingedIntegerWidths-CEIL_INT(realSize);
       
   634         
       
   635         CalculateCellInPixelsReal(aDim, numItems-1, aAvailablePixels, layoutWidthPx, layoutSizePx, sumIntegerWidths, sumCeilingIntegerWidths);
       
   636         realPos += (aAvailablePixels-sumCeilingIntegerWidths)/2;   
       
   637         realSize = CEIL(realSize);
       
   638         }
       
   639     else
       
   640         {
       
   641         // For PC-lint
       
   642         }
       
   643 
       
   644     realPos = ProportionalInnerOuterPadding(aDim, innerPadPos, realPos);
       
   645     
       
   646     aPos = TInt(realPos);
       
   647     aSize = TInt(realSize);
       
   648     }
       
   649 
       
   650 TReal32 CHuiGridLayout::ProportionalInnerOuterPadding(  
       
   651     THuiGridDimension aDim,
       
   652     TReal32 aInnerPadPos,
       
   653     TReal32 aOuterPadPos) const
       
   654     {
       
   655     THuiRealPoint innerPaddingPx = MetricToPixels(InnerPadding(), EHuiReferenceStateTarget);
       
   656     THuiRealRect outerPaddingPx = PaddingInPixels(EHuiReferenceStateTarget);
       
   657     TAxis& axis = iGridLayoutData->iAxes[aDim]; 
       
   658     TUint flag = axis.iLayoutFlags;    
       
   659     TReal32 totalPadding;
       
   660     TReal32 meanOuterPadding;
       
   661     
       
   662     if ( HuiUtil::RealCompare( aInnerPadPos, aOuterPadPos ) )
       
   663         {
       
   664         // Same pos, nothing to do.
       
   665         return aOuterPadPos;
       
   666         }
       
   667     
       
   668     if (aDim==EHuiGridColumn)
       
   669         {
       
   670         meanOuterPadding = (outerPaddingPx.iTl.iX+outerPaddingPx.iBr.iX)/2.0f;
       
   671         totalPadding = innerPaddingPx.iX+meanOuterPadding;
       
   672         }
       
   673     else
       
   674         {
       
   675         meanOuterPadding = (outerPaddingPx.iTl.iY+outerPaddingPx.iBr.iY)/2.0f;
       
   676         totalPadding = innerPaddingPx.iY+meanOuterPadding;            
       
   677         }
       
   678     
       
   679     if (totalPadding && ((flag&EHuiGridIncreaseInnerPadding) && (flag&EHuiGridIncreaseOuterPadding))
       
   680                      || ((flag&EHuiGridIncreaseInnerPadding) && (flag&EHuiGridDecreaseOuterPadding))
       
   681                      || ((flag&EHuiGridDecreaseInnerPadding) && (flag&EHuiGridIncreaseOuterPadding))
       
   682                      || ((flag&EHuiGridDecreaseInnerPadding) && (flag&EHuiGridDecreaseOuterPadding)))
       
   683         {
       
   684         // Both inner and outer padding flags are active, linearly interpolate between them based on ratio.    
       
   685         if (aDim==EHuiGridColumn)
       
   686             {
       
   687             return ((innerPaddingPx.iX*aInnerPadPos + meanOuterPadding*aOuterPadPos)/totalPadding);            
       
   688             }
       
   689         else
       
   690             {
       
   691             return ((innerPaddingPx.iY*aInnerPadPos + meanOuterPadding*aOuterPadPos)/totalPadding);            
       
   692             }
       
   693         }
       
   694         
       
   695     return aOuterPadPos;
       
   696     }  
       
   697     
       
   698     
       
   699 void CHuiGridLayout::CalculateCellInPixelsReal(
       
   700     THuiGridDimension aDim, 
       
   701     TInt aIndex, 
       
   702     TReal32 aAvailablePixels, 
       
   703     TReal32& aPos, 
       
   704     TReal32& aSize,
       
   705     TInt& aFloorPixelPos,
       
   706     TInt& aCeilingPixelPos) const
       
   707     {
       
   708     // note that we will add in the inner padding later
       
   709     // total up the pixels or weights on either side of the target block, so that we know what
       
   710     // the total size is that we're sharing out by weight. 
       
   711     // while we're at it we can remember the size of the target block as well (call it "mid")
       
   712     TReal32 totalWeightsValid(0.f);
       
   713     TReal32 totalPixelsValid(0.f);  
       
   714     TReal32 error(0.f);     
       
   715     TInt pixelWeight;
       
   716     TReal32 weightWeight;    
       
   717     
       
   718     TAxis& axis = iGridLayoutData->iAxes[aDim];
       
   719     TInt weightCount = axis.iWeights.Count();
       
   720     
       
   721     aPos = 0;
       
   722     aSize = 0;
       
   723     aFloorPixelPos = 0;
       
   724     aCeilingPixelPos = 0;
       
   725     
       
   726     // First pass to get total weights and pixels.
       
   727     for(TInt ii = 0; ii < weightCount; ii++)
       
   728         {    
       
   729         THuiMetric& weight = axis.iWeights[ii];
       
   730                     
       
   731         WeightFromMetric(aDim, weight, weightWeight, pixelWeight);
       
   732         totalPixelsValid += pixelWeight;
       
   733         totalWeightsValid += weightWeight;
       
   734         }
       
   735 
       
   736     // All the fixed-pixel items have been accounted for, this is
       
   737     // what's left for distribution between the variable, weighted items.    
       
   738     TReal32 remainderPixels = aAvailablePixels - totalPixelsValid;
       
   739 
       
   740     // Second pass to calculate size and pos
       
   741     for(TInt ii = 0; ii <= aIndex; ii++)
       
   742         {
       
   743         TReal32 nextWeight(0.f);
       
   744         TReal32 nextPixels(0.f);
       
   745 
       
   746         // Child visuals that are outside of the specified range of blocks 
       
   747         // should take the weight of the last specified block.
       
   748         THuiMetric weight(1.f, EHuiUnitWeight);
       
   749         if(ii < weightCount)
       
   750             {
       
   751             weight = axis.iWeights[ii];
       
   752             }
       
   753         else if( weightCount ) // return weight of last element
       
   754             {
       
   755             weight = axis.iWeights[weightCount-1];
       
   756             }
       
   757         else
       
   758             {
       
   759             // For PC-lint
       
   760             }
       
   761 
       
   762         WeightFromMetric(aDim, weight, nextWeight, pixelWeight);
       
   763         nextPixels += pixelWeight;
       
   764 
       
   765         TReal32 width;
       
   766         if(totalWeightsValid != 0)
       
   767             {
       
   768             width = (nextWeight / totalWeightsValid) * remainderPixels;
       
   769             }
       
   770         else
       
   771             {
       
   772             width = 0;
       
   773             }
       
   774         
       
   775         aFloorPixelPos += FLOOR_INT(width);
       
   776         aCeilingPixelPos += CEIL_INT(width);     
       
   777         aFloorPixelPos += nextPixels;
       
   778         aCeilingPixelPos += nextPixels;             
       
   779         
       
   780         error += FRAC(width);
       
   781 
       
   782         if ((axis.iLayoutFlags == 0))
       
   783             {
       
   784             if (error >= 0.5)
       
   785                 {
       
   786                 // There is a rounding error here, so increase size if no flags forcing exact-size are set
       
   787                 error--;
       
   788                 width = CEIL(width);
       
   789                 }
       
   790             else
       
   791                 {
       
   792                 width = FLOOR(width);
       
   793                 }
       
   794             }
       
   795             
       
   796         if(ii < aIndex)
       
   797             {
       
   798             aPos += width;            
       
   799             aPos += nextPixels;
       
   800             }
       
   801         else
       
   802             {
       
   803             aSize += width;
       
   804             aSize += nextPixels;
       
   805             }                    
       
   806         }
       
   807     }
       
   808 
       
   809 void CHuiGridLayout::WeightFromMetric(THuiGridDimension aDim, THuiMetric& aMetric, TReal32& aWeight, TInt& aPix) const
       
   810     {
       
   811     aWeight = 0.0f;
       
   812     aPix = 0;
       
   813     
       
   814     switch(aMetric.iUnit)
       
   815         {
       
   816         case EHuiUnitWeight:
       
   817             {
       
   818             aWeight = aMetric.iMagnitude;
       
   819             break;
       
   820             }
       
   821         case EHuiUnitPixel:
       
   822             {
       
   823             // slight optimization here as we know it's pixels
       
   824             aPix = HUI_ROUND_FLOAT_TO_INT(aMetric.iMagnitude);
       
   825             break;
       
   826             }
       
   827         case EHuiUnitNormalized:
       
   828         case EHuiUnitRelativeToDisplay:
       
   829         case EHuiUnitRelativeToMySize:
       
   830         case EHuiUnitS60:
       
   831             {
       
   832             THuiRealPoint refPx = MetricToPixels(THuiXYMetric(aMetric), EHuiReferenceStateTarget);
       
   833             aPix = (aDim == EHuiGridColumn) ? HUI_ROUND_FLOAT_TO_INT(refPx.iX) : HUI_ROUND_FLOAT_TO_INT(refPx.iY);
       
   834             break;
       
   835             }
       
   836         default:
       
   837             break;
       
   838         }
       
   839     }