--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluirendering/uiengine/src/xnuiengineimpl.cpp Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,10024 @@
+/*
+* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Layout calculation and UI rendering mechanism implementations.
+*
+*/
+
+
+// System includes
+#include <utf.h>
+#include <eikapp.h>
+#include <AknUtils.h>
+#include <layoutmetadata.cdl.h>
+
+// User includes
+#include "xnuiengine.h"
+#include "xnuiengineimpl.h"
+#include "xnuistatelistener.h"
+#include "xnpointerarray.h"
+#include "xnodt.h"
+#include "xndomlist.h"
+#include "xndompropertyvalue.h"
+#include "xnmenuadapter.h"
+#include "xnpopupcontroladapter.h"
+#include "xnviewdata.h"
+#include "xnnodebreadthfirstiterator.h"
+#include "xntype.h"
+#include "xnnodepluginif.h"
+#include "xncomponentnodeimpl.h"
+#include "xnproperty.h"
+#include "xnappuiadapter.h"
+#include "xnviewadapter.h"
+#include "xnwidgetextensionadapter.h"
+#include "xnscrollablecontroladapter.h"
+#include "xnkeyeventdispatcher.h"
+#include <aknlayoutscalable_avkon.cdl.h>
+#include "xuikon_builds_cfg.hrh"
+#include "xndomdocument.h"
+#include "xndomnode.h"
+#include "xneditmode.h"
+#include "xnhittest.h"
+#include "xnnode.h"
+#include "xnpanic.h"
+#include "xneffectmanager.h"
+
+#ifdef _XN_PERFORMANCE_TEST_
+#include "xntimemon.h"
+#endif
+
+// CONSTANTS
+const TInt KXnBorderThin = 1;
+const TInt KXnBorderMedium = 3;
+const TInt KXnBorderThick = 5;
+const TInt KXnStackPriorityKeyEventDispatcher = 55;
+const TInt KFocusGrowValue = 3;
+
+_LIT8( KBoxNodeName, "box" );
+_LIT8( KButtonNodeName, "button" );
+_LIT8( KWidgetNodeName, "widget" );
+_LIT8( KWidgetExtensionNodeName, "widgetextension" );
+_LIT8( KScrollableBoxNodeName, "scrollablebox" );
+_LIT8( KMenuBar, "menubar" );
+_LIT8( KPopUpNodeName, "popup" );
+
+_LIT8( KPlugin, "plugin" );
+
+// LOCAL CONSTANTS AND MACROS
+static const TReal KIntConversionConstant = 0.5;
+static const TReal KIntPercentageConstant =
+ static_cast< TReal >( 1 ) / static_cast< TReal >( 100 );
+static const TReal KInchesAsTwips = 1440;
+static const TReal KCentimetersAsInches = static_cast< TReal >( 1 ) / 2.54;
+static const TReal KCentimetersAsTwips = KCentimetersAsInches * KInchesAsTwips;
+static const TReal KMillimetersAsInches =
+ KCentimetersAsInches / static_cast< TReal >( 10 );
+static const TReal KMillimetersAsTwips = KMillimetersAsInches * KInchesAsTwips;
+static const TReal KPointsAsInches =
+ static_cast< TReal >( 1 ) / static_cast< TReal >( 72 );
+static const TReal KPointsAsTwips = KPointsAsInches * KInchesAsTwips;
+static const TReal KPicasAsInches =
+ KPointsAsInches / static_cast< TReal >( 12 );
+static const TReal KPicasAsTwips = KPicasAsInches * KInchesAsTwips;
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+static TRect AddRect( const TRect& aOriginal, const TRect& aAdded );
+static TRect SubtractRect( const TRect& aOriginal, const TRect& aSubtracter );
+static TSize AutoStaticBTL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static TSize AutoStaticLRL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static TSize AutoStaticRLL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static TSize AutoStaticTBL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static void CalculateAbsolutePositionsL( CXnNode& aNode,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static void CalculateBorderL( CXnNode& aNode,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static void CalculateMarginL( CXnNode& aParent, CXnNode& aNode,
+ CXnNode* aPreviousSibling, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels, TInt& aColumnWidth, TInt& aColumnMargin );
+static void CalculatePaddingL( const TRect& aParentRect, CXnNode& aNode,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+
+static void CalculateRectL( CXnNode& aNode, CXnNode& aParent,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+
+static void CalculateRelativePositionsL( const TRect& aRect, CXnNode& aNode,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static TSize CalculateSpaceUsedByChildrenL( RPointerArray< CXnNode >& aChildren,
+ CXnNode& aNode, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, CGraphicsDevice& aScreenDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+
+static TSize CalculateTotalDimensionsL( CXnNode& aNode, TBool aIgnoreAutoValues,
+ TBool aIgnoreMinSizes, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static TBool CutOnePixelFromPercentChildNodeL( CXnNode& aNode,
+ const TDesC8& aParentBlockProgression );
+static void DetermineBorderWidthsL( CXnProperty* aBorderWidthProperty,
+ TInt& aBordervertical, TInt& aBorderhorizontal,
+ TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static TInt DisplayedChildrenCountL( CXnNode& aNode,
+ RPointerArray< CXnNode >* aDisplayedChildren = NULL );
+static CXnNode* DisplayedParentL( CXnNode& aNode );
+static CXnDomPropertyValue* DomPropertyValueFromProperty(
+ CXnProperty* aProperty );
+static void DropExceedingRectL( const TRect& aParentRect, CXnNode& aNode,
+ TBool aDropRelativeNode = EFalse );
+static TBool CalculateExceedingArea( CXnNode& aParent, CXnNode& aChild,
+ TInt& aLeftOffset, TInt& aRightOffset, TInt& aTopOffset,
+ TInt& aBottomOffset );
+static void AdjustRectsL( CXnNode& aNode, TInt aLeftOffset, TInt aRightOffset,
+ TInt aTopOffset, TInt aBottomOffset );
+static void ClearRects( CXnNode& aNode, TBool aRecurse = EFalse );
+static void FitChildrenIntoParentL( CXnNode& aNode,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static TInt GetPositionL( CXnNode& aNode,
+ const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection );
+static TInt HasNodeAutoValuesL( CXnNode& aNode );
+static TInt HasNodeHorizontalAutoValuesL( CXnNode& aNode );
+static TInt HasNodeVerticalAutoValuesL( CXnNode& aNode );
+static TBool HasNodeMinSizesL( CXnNode& aNode );
+static TBool HasNodeMaxSizesL( CXnNode& aNode );
+static TInt HorizontalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels );
+static TInt HorizontalValueToPixelsL( CXnDomPropertyValue* aValue,
+ TReal aReferenceValue, CGraphicsDevice& aScreenDevice,
+ TReal aHorizontalUnitInPixels );
+static void GrowToMinSizeL( CXnNode& aNode, TRect& aParentRect,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static void ShrinkToMaxSizeL( CXnNode& aNode, TRect& aParentRect,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static TBool IsAbsoluteL( CXnNode& aNode );
+static TBool IsLargerThanMaxSizeL( const TRect& aParentRect, CXnNode& aNode,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static TBool IsNodeDisplayedL( CXnNode& aNode );
+
+static TBool IsNodeTooltip( CXnNode& aNode );
+static TBool IsPropertyAutoL( CXnProperty& aProperty );
+static TBool IsPropertyNone( CXnProperty& aProperty );
+static TBool IsRelativeL( CXnNode& aNode );
+static TBool IsSmallerThanMinSizeL( const TRect& aParentRect, CXnNode& aNode,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static TBool IsValuePercentageL( CXnProperty& aProperty );
+static TInt PercentageToPixelsL( TReal& aPercentage, TReal aReferenceValue );
+static void PlaceAreasL( CXnNode& aNode,
+ RPointerArray< CXnNode >& aLaidOutList,
+ TInt aLayoutPhase, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static void PriorizeChildrenL( CXnNode& aNode );
+static void CalculateAutoPropertiesOfNodesL(
+ RPointerArray< CXnNode >* aAutoNodeArray, TInt& aWidthAutoCount,
+ TInt& aHeightAutoCount );
+static void ProcessAutoAreasL( CXnNode& aParentNode,
+ RPointerArray< CXnNode >* aArray, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
+static void CalculateCollapseMarginsL( RPointerArray< CXnNode >& aChildren,
+ RArray< TInt >& aCollapsedMarginsWidth,
+ RArray< TInt >& aCollapsedMarginsHeight,
+ const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection );
+static TSize CalculateSpaceUsedByAutoChildrenL(
+ RPointerArray< CXnNode >& aAutoChildren,
+ RPointerArray< CXnNode >& aCalculatedAutoChildren,
+ CXnNode& aParent,
+ const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection,
+ CGraphicsDevice& aScreenDevice );
+static void MoveAutoAreaL( TRect& parentRect,
+ RPointerArray< CXnNode >& aChildren,
+ const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection );
+static TSize ScaleAutoAreaL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+static void FitAutoChildrenIntoParentL( RPointerArray< CXnNode >& aAutoChildren,
+ RPointerArray< CXnNode >& aCalculatedAutoChildren, CXnNode& aParent,
+ const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
+ CGraphicsDevice& aGraphicsDevice );
+static TInt VerticalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
+ CGraphicsDevice& aScreenDevice, TReal aVerticalUnitInPixels );
+static TInt VerticalValueToPixelsL( CXnDomPropertyValue* aValue,
+ TReal aReferenceValue, CGraphicsDevice& aScreenDevice,
+ TReal aVerticalUnitInPixels );
+static TBool IsStringValueL( CXnProperty& aProperty );
+static TInt HorizontalUnitsToPixelsL( TReal aUnits,
+ TReal aHorizontalUnitInPixels );
+static TInt VerticalUnitsToPixelsL( TReal aUnits, TReal aVerticalUnitInPixels );
+static void ProcessAdaptiveAreasL( CXnNode& aParent,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+
+static void CalculateAdaptiveSizeL( CXnNode& aNode,
+ const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels );
+
+static CXnNode* BuildTriggerNodeLC( CXnUiEngine& aUiEngine,
+ const TDesC8& aTriggerName );
+static void UpdateInternalUnits( TReal& aHorizontalUnitInPixels,
+ TReal& aVerticalUnitInPixels, TRect aRect );
+static CXnNode* BuildScreenDeviceChangeTriggerNodeLC(
+ CXnUiEngine& aUiEngine );
+static void FillFocusCandidatesL( CXnNode* aParent,
+ RPointerArray< CXnNode >& aArray );
+static TInt DetermineStatusPaneLayout( CXnProperty* aProperty );
+static TBool SetAdaptivesL( CXnNode& aNode );
+
+static void FindNodeByClassL( CXnNode* aRootNode, const TDesC8& aClassId,
+ CXnPointerArray& aArray, const TDesC8& aNamespace );
+static CXnNode* FindNodeByIdL( CXnNode* aRootNode, const TDesC8& aAreaId,
+ const TDesC8& aNamespace );
+
+#ifdef _XN3_DEBUG_
+static void TraceTreeL( CXnNode* aRootNode );
+#endif
+
+// ============================= LOCAL FUNCTIONS ===============================
+// -----------------------------------------------------------------------------
+// GrowIfNeeded()
+// When a plugin is focused, the focus is a bit bigger than its control
+// (this is a hack fix to get focus visible with WRT widgets).
+// Therefore we need to check if focused node is a plugin,
+// or focused node has same size with its plugin, and grow dirty rect accordingly.
+// -----------------------------------------------------------------------------
+//
+static void GrowIfNeeded(CXnNode* aNode, TRect& aRect)
+ {
+ CXnNode* focusedNode(NULL);
+ for( CXnNode* node = aNode; node; node = node->Parent() )
+ {
+ if( node->IsStateSet( XnPropertyNames::style::common::KFocus ) )
+ {
+ if( node->DomNode()->Name() == KPlugin )
+ {
+ CXnControlAdapter* adapter( node->Control() );
+ if(adapter)
+ {
+ aRect = adapter->Rect();
+ aRect.Grow( KFocusGrowValue, KFocusGrowValue );
+ }
+ break;
+ }
+ focusedNode = node;
+ }
+ else if( node->DomNode()->Name() == KPlugin )
+ {
+ if( focusedNode && focusedNode->MarginRect() == node->Rect() )
+ {
+ CXnControlAdapter* adapter( focusedNode->Control() );
+ if(adapter)
+ {
+ aRect = adapter->Rect();
+ aRect.Grow( KFocusGrowValue, KFocusGrowValue );
+ }
+ }
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+static TBool IsSrollableBox( CXnNode& aNode )
+ {
+ if( aNode.Type()->Type() == KScrollableBoxNodeName )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// FindNodeByClassL()
+// Finds recursively a node from current view by class
+// -----------------------------------------------------------------------------
+//
+static void FindNodeByClassL( CXnNode* aRootNode, const TDesC8& aClassId,
+ CXnPointerArray& aArray, const TDesC8& aNamespace )
+ {
+ ASSERT( aRootNode );
+
+ if ( aNamespace != KNullDesC8 && aNamespace != aRootNode->Namespace() )
+ {
+ // Recursed to wrong namespace
+ return;
+ }
+
+ CXnProperty* prop( aRootNode->ClassL() );
+
+ if ( prop && prop->StringValue() == aClassId )
+ {
+ // Correct id found
+ if ( aNamespace == KNullDesC8 )
+ {
+ aArray.Container().AppendL( aRootNode );
+ }
+ else if ( aNamespace == aRootNode->DomNode()->Namespace() )
+ {
+ // Namespace is defined and this node is in that namespace
+ // -> this is perfect match
+ aArray.Container().AppendL( aRootNode );
+ }
+ }
+
+ // Recurse children
+ RPointerArray< CXnNode >& children( aRootNode->Children() );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ FindNodeByClassL( children[i], aClassId, aArray, aNamespace );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// FindNodeByIdL()
+// Finds recursively a node from current view by id
+// -----------------------------------------------------------------------------
+//
+static CXnNode* FindNodeByIdL( CXnNode* aRootNode, const TDesC8& aAreaId,
+ const TDesC8& aNamespace )
+ {
+ ASSERT( aRootNode );
+
+ if ( aNamespace != KNullDesC8 && aNamespace != aRootNode->Namespace() )
+ {
+ // Recursed to wrong namespace
+ return NULL;
+ }
+
+ CXnProperty* prop( aRootNode->IdL() );
+
+ if ( prop && prop->StringValue() == aAreaId )
+ {
+ // Correct id found
+ if ( aNamespace == KNullDesC8 )
+ {
+ // No namespace defined, so this is the first found best match
+ return aRootNode;
+ }
+ else if ( aNamespace == aRootNode->DomNode()->Namespace() )
+ {
+ // Namespace is defined and this node is in that namespace
+ // -> this is perfect match
+ return aRootNode;
+ }
+ }
+
+ // No match found, recurse children
+ RPointerArray< CXnNode >& children( aRootNode->Children() );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNode* retval( FindNodeByIdL( children[i], aAreaId, aNamespace ) );
+
+ if ( retval )
+ {
+ return retval;
+ }
+ }
+
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// AutoStaticVerticalBTL()
+// Calculate properties set to AUTO when positioning is static, layout vertical
+// and direction right-to-left
+// -----------------------------------------------------------------------------
+//
+static TSize AutoStaticBTL( CXnNode& aNode, TInt aWidthToFit, TInt aHeightToFit,
+ RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ // Static positioning, vertical, right to left
+ TBool horizontalMarginProcessed = EFalse;
+ TBool verticalMarginProcessed = EFalse;
+ TBool allVerticalValuesProcessed = EFalse;
+ TBool allHorizontalValuesProcessed = EFalse;
+
+ CXnProperty* maxHeightProperty = aNode.MaxHeightL();
+ CXnProperty* maxWidthProperty = aNode.MaxWidthL();
+ CXnProperty* minHeightProperty = aNode.MinHeightL();
+ CXnProperty* minWidthProperty = aNode.MinWidthL();
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+
+ TSize size = CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
+
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ // search for height property
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KHeight )
+ {
+ // height was AUTO, all other vertical auto values are 0
+ TInt newHeight = aHeightToFit - size.iHeight;
+
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect ( normalFlowBorderRect,
+ contentRect ) );
+
+ // grow height to fill the void
+ contentRect.SetHeight( newHeight );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( size.iWidth, aHeightToFit );
+ }
+ }
+
+ // if exactly one value is AUTO, value is computed to make equality true
+ if ( aAutoProperties.Count() == 1 )
+ {
+ if ( !allHorizontalValuesProcessed )
+ {
+ const TDesC8& attributeName = aAutoProperties[0];
+ if ( attributeName == XnPropertyNames::style::common::KWidth )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect( paddingRect,
+ contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect,
+ contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect,
+ contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow width to fill the void
+ contentRect.SetWidth( remainingWidth );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( aWidthToFit, size.iHeight );
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginLeft )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ contentRect.Move( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ marginRect.Resize( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ marginRect.Resize( 0, remainingHeight );
+ marginRect.Move( 0, -remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ marginRect.Resize( 0, remainingHeight );
+ marginRect.Move( 0, -remainingHeight );
+ paddingRect.Move( 0, -remainingHeight );
+ borderRect.Move( 0, -remainingHeight );
+ normalFlowBorderRect.Move( 0, -remainingHeight );
+ contentRect.Move( 0, -remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+ }
+ }
+ else
+ {
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KWidth )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect(
+ borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect(
+ marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow width to fill the void
+ contentRect.SetWidth( remainingWidth );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect(
+ contentRect, normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( aWidthToFit, size.iHeight );
+ }
+
+ // several auto properties
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is right margin also set to AUTO?
+ CXnProperty* rightMargin = aNode.MarginRightL();
+ if ( rightMargin )
+ {
+ if ( IsPropertyAutoL( *rightMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( ( remainingWidth / 2 ), 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ borderRect.Move( ( remainingWidth / 2 ), 0 );
+ normalFlowBorderRect.Move( (
+ remainingWidth / 2 ), 0 );
+ paddingRect.Move( remainingWidth / 2, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only left margin set to AUTO
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( ( remainingWidth ), 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is left margin also set to AUTO?
+ CXnProperty* leftMargin = aNode.MarginLeftL();
+ if ( leftMargin )
+ {
+ if ( IsPropertyAutoL( *leftMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ contentRect.Move( remainingWidth / 2, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ borderRect.Move( ( remainingWidth / 2 ), 0 );
+ normalFlowBorderRect.Move( (
+ remainingWidth / 2 ), 0 );
+ paddingRect.Move( remainingWidth / 2, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only right margin set to AUTO
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ marginRect.Resize( remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ if ( !verticalMarginProcessed &&
+ !allVerticalValuesProcessed )
+ {
+ // is bottom margin also set to AUTO?
+ CXnProperty* bottomMargin = aNode.MarginBottomL();
+ if ( bottomMargin )
+ {
+ if ( IsPropertyAutoL( *bottomMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ contentRect.Move( 0, remainingHeight / 2 );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, ( remainingHeight / 2 ) );
+ normalFlowBorderRect.Move(
+ 0, ( remainingHeight / 2 ) );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only top margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ marginRect.Resize( 0, remainingHeight );
+ marginRect.Move( 0, -remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is top margin also set to AUTO?
+ CXnProperty* topMargin = aNode.MarginTopL();
+ if ( topMargin )
+ {
+ if ( IsPropertyAutoL( *topMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ contentRect.Move( 0, -( remainingHeight / 2 ) );
+ marginRect.Resize( 0, remainingHeight );
+ marginRect.Move( 0, -remainingHeight );
+ borderRect.Move( 0, -( remainingHeight / 2 ) );
+ normalFlowBorderRect.Move(
+ 0, -( remainingHeight / 2 ) );
+ paddingRect.Move( 0, -( remainingHeight / 2 ) );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only bottom margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ contentRect.Move( 0, -remainingHeight );
+ marginRect.Resize( 0, remainingHeight );
+ marginRect.Move( 0, -remainingHeight );
+ borderRect.Move( 0, -remainingHeight );
+ normalFlowBorderRect.Move(
+ 0, -remainingHeight );
+ paddingRect.Move( 0, -remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+ }
+ }
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ return contentRect.Size();
+ }
+
+// -----------------------------------------------------------------------------
+// AutoStaticLRL()
+// Calculate properties set to AUTO when positioning is static,
+// layout horizontal
+// and direction left-to-right
+// -----------------------------------------------------------------------------
+//
+static TSize AutoStaticLRL( CXnNode& aNode, TInt aWidthToFit, TInt aHeightToFit,
+ RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ // Static positioning, horizontal, left to right
+ TBool horizontalMarginProcessed = EFalse;
+ TBool verticalMarginProcessed = EFalse;
+ TBool allVerticalValuesProcessed = EFalse;
+ TBool allHorizontalValuesProcessed = EFalse;
+
+ CXnProperty* maxHeightProperty = aNode.MaxHeightL();
+ CXnProperty* maxWidthProperty = aNode.MaxWidthL();
+ CXnProperty* minHeightProperty = aNode.MinHeightL();
+ CXnProperty* minWidthProperty = aNode.MinWidthL();
+
+ TRect contentRect = aNode.Rect();
+ TRect paddingRect = aNode.PaddingRect();
+ TRect borderRect = aNode.BorderRect();
+ TRect marginRect = aNode.MarginRect();
+ TRect normalFlowBorderRect = aNode.NormalFlowBorderRect();
+ TSize size = CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
+
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ // search for width property
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KWidth )
+ {
+ // width was AUTO, all other vertical auto values are 0
+ TInt newWidth = aWidthToFit - size.iWidth;
+
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect( normalFlowBorderRect,
+ contentRect ) );
+
+ // grow width to fill the void
+ contentRect.SetWidth( newWidth );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect(
+ contentRect, normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( aWidthToFit, size.iHeight );
+ allHorizontalValuesProcessed = ETrue;
+ }
+ }
+
+ // if exactly one value is AUTO, value is computed to make equality true
+ if ( aAutoProperties.Count() == 1 )
+ {
+ if ( !allHorizontalValuesProcessed )
+ {
+ const TDesC8& attributeName = aAutoProperties[0];
+ if ( attributeName == XnPropertyNames::style::common::KHeight )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect(
+ borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect(
+ marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow height to fill the void
+ contentRect.SetHeight( remainingHeight );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect(
+ contentRect, normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+ size = TSize( size.iWidth, aHeightToFit );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ marginRect.Resize( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight / 2 );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ borderRect.Move( 0, remainingHeight / 2 );
+ normalFlowBorderRect.Move( 0, remainingHeight / 2 );
+ marginRect.Resize( 0, remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ marginRect.Resize( 0, remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+ }
+ }
+ else
+ {
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KHeight )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect(
+ borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect(
+ marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow height to fill the void
+ contentRect.SetHeight( remainingHeight );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect(
+ contentRect, normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+ size = TSize( size.iWidth, aHeightToFit );
+ }
+
+ // several auto properties
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is right margin also set to AUTO?
+ CXnProperty* rightMargin = aNode.MarginRightL();
+ if ( rightMargin )
+ {
+ if ( IsPropertyAutoL( *rightMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( ( remainingWidth / 2 ), 0 );
+ horizontalMarginProcessed = ETrue;
+ marginRect.Resize( ( remainingWidth ), 0 );
+ borderRect.Move( ( remainingWidth / 2 ), 0 );
+ normalFlowBorderRect.Move( (
+ remainingWidth / 2 ), 0 );
+ paddingRect.Move( ( remainingWidth / 2 ), 0 );
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only left margin set to AUTO
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ marginRect.Move( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is left margin also set to AUTO?
+ CXnProperty* leftMargin = aNode.MarginLeftL();
+ if ( leftMargin )
+ {
+ if ( IsPropertyAutoL( *leftMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( ( remainingWidth / 2 ), 0 );
+ horizontalMarginProcessed = ETrue;
+ marginRect.Resize( ( remainingWidth ), 0 );
+ borderRect.Move( ( remainingWidth / 2 ), 0 );
+ normalFlowBorderRect.Move( (
+ remainingWidth / 2 ), 0 );
+ paddingRect.Move( ( remainingWidth / 2 ), 0 );
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only right margin set to AUTO
+ horizontalMarginProcessed = ETrue;
+ }
+ }
+ }
+ }
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is bottom margin also set to AUTO?
+ CXnProperty* bottomMargin = aNode.MarginBottomL();
+ if ( bottomMargin )
+ {
+ if ( IsPropertyAutoL( *bottomMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, ( remainingHeight / 2 ) );
+ verticalMarginProcessed = ETrue;
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, ( remainingHeight / 2 ) );
+ normalFlowBorderRect.Move(
+ 0, ( remainingHeight / 2 ) );
+ paddingRect.Move( 0, ( remainingHeight / 2 ) );
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only top margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight );
+ verticalMarginProcessed = ETrue;
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, remainingHeight );
+ normalFlowBorderRect.Move( 0, remainingHeight );
+ paddingRect.Move( 0, remainingHeight );
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is top margin also set to AUTO?
+ CXnProperty* topMargin = aNode.MarginTopL();
+ if ( topMargin )
+ {
+ if ( IsPropertyAutoL( *topMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight / 2 );
+ verticalMarginProcessed = ETrue;
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, remainingHeight / 2 );
+ normalFlowBorderRect.Move(
+ 0, remainingHeight / 2 );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only bottom margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ marginRect.Resize( 0, remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+ }
+ }
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ return contentRect.Size();
+ }
+
+// -----------------------------------------------------------------------------
+// AutoStaticRLL()
+// Calculate properties set to AUTO when positioning is static,
+// layout horizontal
+// and direction right-to-left.
+// -----------------------------------------------------------------------------
+//
+static TSize AutoStaticRLL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ // Static positioning, horizontal, right to left
+ TBool horizontalMarginProcessed = EFalse;
+ TBool verticalMarginProcessed = EFalse;
+ TBool allVerticalValuesProcessed = EFalse;
+ TBool allHorizontalValuesProcessed = EFalse;
+
+ CXnProperty* maxHeightProperty = aNode.MaxHeightL();
+ CXnProperty* maxWidthProperty = aNode.MaxWidthL();
+ CXnProperty* minHeightProperty = aNode.MinHeightL();
+ CXnProperty* minWidthProperty = aNode.MinWidthL();
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+
+ TSize size = CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
+
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ // search for height property
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KWidth )
+ {
+ TInt newWidth = aWidthToFit - size.iWidth;
+
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect( normalFlowBorderRect,
+ contentRect ) );
+
+ // grow width to fill the void
+ contentRect.SetWidth( newWidth );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( aWidthToFit, size.iHeight );
+ allHorizontalValuesProcessed = ETrue;
+ }
+ }
+
+ // if exactly one value is AUTO, value is computed to make equality true
+ if ( aAutoProperties.Count() == 1 )
+ {
+ if ( !allHorizontalValuesProcessed )
+ {
+ const TDesC8& attributeName = aAutoProperties[0];
+ if ( attributeName == XnPropertyNames::style::common::KHeight )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow height to fill the void
+ contentRect.SetHeight( remainingHeight );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( size.iWidth, aHeightToFit );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ marginRect.Move( -remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ contentRect.Move( -remainingWidth, 0 );
+ paddingRect.Move( -remainingWidth, 0 );
+ borderRect.Move( -remainingWidth, 0 );
+ normalFlowBorderRect.Move( -remainingWidth, 0 );
+ marginRect.Move( -remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight / 2 );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ borderRect.Move( 0, remainingHeight / 2 );
+ normalFlowBorderRect.Move( 0, remainingHeight / 2 );
+ marginRect.Resize( 0, remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ marginRect.Resize( 0, remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+ }
+ }
+ else
+ {
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KHeight )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow height to fill the void
+ contentRect.SetHeight( remainingHeight );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+
+ // several auto properties
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is right margin also set to AUTO?
+ CXnProperty* rightMargin = aNode.MarginRightL();
+ if ( rightMargin )
+ {
+ if ( IsPropertyAutoL( *rightMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect left
+ contentRect.Move( -( remainingWidth / 2 ), 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ marginRect.Move( -remainingWidth, 0 );
+ borderRect.Move( -( remainingWidth / 2 ), 0 );
+ normalFlowBorderRect.Move(
+ -( remainingWidth / 2 ), 0 );
+ paddingRect.Move( -( remainingWidth / 2 ), 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only left margin set to AUTO
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect left
+ contentRect.Move( ( remainingWidth ), 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ marginRect.Move( remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is left margin also set to AUTO?
+ CXnProperty* leftMargin = aNode.MarginLeftL();
+ if ( leftMargin )
+ {
+ if ( IsPropertyAutoL( *leftMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ contentRect.Move( -( remainingWidth / 2 ), 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ marginRect.Move( -remainingWidth, 0 );
+ borderRect.Move( -( remainingWidth / 2 ), 0 );
+ normalFlowBorderRect.Move(
+ -( remainingWidth / 2 ), 0 );
+ paddingRect.Move( -( remainingWidth / 2 ), 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only right margin set to AUTO
+ TInt usedWidth = size.iWidth;
+ TInt remainingWidth = aWidthToFit - usedWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ contentRect.Move( -remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ marginRect.Move( -remainingWidth, 0 );
+ borderRect.Move( -remainingWidth, 0 );
+ normalFlowBorderRect.Move( -remainingWidth, 0 );
+ paddingRect.Move( -remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is bottom margin also set to AUTO?
+ CXnProperty* bottomMargin = aNode.MarginBottomL();
+ if ( bottomMargin )
+ {
+ if ( IsPropertyAutoL( *bottomMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ contentRect.Move( 0, ( remainingHeight / 2 ) );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, ( remainingHeight / 2 ) );
+ normalFlowBorderRect.Move(
+ 0, ( remainingHeight / 2 ) );
+ paddingRect.Move( 0, ( remainingHeight / 2 ) );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only top margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ contentRect.Move( 0, remainingHeight );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, remainingHeight );
+ normalFlowBorderRect.Move( 0, remainingHeight );
+ paddingRect.Move( 0, remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is top margin also set to AUTO?
+ CXnProperty* topMargin = aNode.MarginTopL();
+ if ( topMargin )
+ {
+ if ( IsPropertyAutoL( *topMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, ( remainingHeight / 2 ) );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, ( remainingHeight / 2 ) );
+ normalFlowBorderRect.Move(
+ 0, ( remainingHeight / 2 ) );
+ paddingRect.Move( 0, ( remainingHeight / 2 ) );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only bottom margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ marginRect.Resize( 0, remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+ }
+ }
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ return contentRect.Size();
+ }
+
+// -----------------------------------------------------------------------------
+// SubtractRect()
+// Calculate the difference of two rectangles and return it as
+// -----------------------------------------------------------------------------
+//
+static TRect SubtractRect( const TRect& aOriginal, const TRect& aSubtracter )
+ {
+ return TRect( aOriginal.iTl.iX - aSubtracter.iTl.iX,
+ aOriginal.iTl.iY - aSubtracter.iTl.iY,
+ aOriginal.iBr.iX - aSubtracter.iBr.iX,
+ aOriginal.iBr.iY - aSubtracter.iBr.iY );
+ }
+
+// -----------------------------------------------------------------------------
+// AddRect()
+// Add two rectangles together and return the result
+// -----------------------------------------------------------------------------
+//
+static TRect AddRect( const TRect& aOriginal, const TRect& aAdded )
+ {
+ return TRect( aOriginal.iTl.iX + aAdded.iTl.iX,
+ aOriginal.iTl.iY + aAdded.iTl.iY,
+ aOriginal.iBr.iX + aAdded.iBr.iX,
+ aOriginal.iBr.iY + aAdded.iBr.iY );
+ }
+
+// -----------------------------------------------------------------------------
+// AutoStaticTBL()
+// Calculate properties set to AUTO when positioning is static, layout vertical
+// and direction left-to-right
+// -----------------------------------------------------------------------------
+//
+static TSize AutoStaticTBL( CXnNode& aNode, TInt aWidthToFit, TInt aHeightToFit,
+ RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ // Static positioning, vertical, left to right
+ TBool horizontalMarginProcessed( EFalse );
+ TBool verticalMarginProcessed( EFalse );
+ TBool allVerticalValuesProcessed( EFalse );
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+
+ TSize size( CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
+
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ // search for height property
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KHeight )
+ {
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect( normalFlowBorderRect,
+ contentRect ) );
+
+ // grow height to fill the void
+ contentRect.SetHeight( aHeightToFit - size.iHeight );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect(
+ contentRect, normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+ size = TSize( size.iWidth, aHeightToFit );
+ allVerticalValuesProcessed = ETrue;
+ }
+ }
+
+ // if exactly one value is AUTO, value is computed to make equality true
+ if ( aAutoProperties.Count() == 1 )
+ {
+ if ( !allVerticalValuesProcessed )
+ {
+ const TDesC8& attributeName = aAutoProperties[0];
+ if ( attributeName == XnPropertyNames::style::common::KWidth )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow width to fill the void
+ contentRect.SetWidth( remainingWidth );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+ size = TSize( aWidthToFit, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ marginRect.Resize( remainingWidth, 0 );
+ size = TSize( size.iWidth + remainingWidth, size.iHeight );
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight / 2 );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ borderRect.Move( 0, remainingHeight / 2 );
+ normalFlowBorderRect.Move( 0, remainingHeight / 2 );
+ marginRect.Resize( 0, remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // set margin rect
+ marginRect.Resize( 0, remainingHeight );
+ size = TSize( size.iWidth, size.iHeight + remainingHeight );
+ }
+ }
+ }
+ else
+ {
+ for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
+ {
+ const TDesC8& attributeName = aAutoProperties[i];
+ if ( attributeName == XnPropertyNames::style::common::KWidth )
+ {
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // Calculate the difference so that it can be returned
+ TRect paddingRectDiff( SubtractRect(
+ paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ // grow width to fill the void
+ contentRect.SetWidth( remainingWidth );
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ normalFlowBorderRect = AddRect( contentRect,
+ normalFlowBorderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+ size = TSize( aWidthToFit, size.iHeight );
+ }
+
+ // several auto properties
+ if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is right margin also set to AUTO?
+ CXnProperty* rightMargin = aNode.MarginRightL();
+ if ( rightMargin )
+ {
+ if ( IsPropertyAutoL( *rightMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move(( remainingWidth / 2 ), 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ borderRect.Move( remainingWidth / 2, 0 );
+ normalFlowBorderRect.Move( remainingWidth / 2, 0 );
+ paddingRect.Move( remainingWidth / 2, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only left margin set to AUTO
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( remainingWidth, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ borderRect.Move( remainingWidth, 0 );
+ normalFlowBorderRect.Move( remainingWidth, 0 );
+ paddingRect.Move( remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginRight )
+ {
+ if ( !horizontalMarginProcessed )
+ {
+ // is left margin also set to AUTO?
+ CXnProperty* leftMargin = aNode.MarginLeftL();
+ if ( leftMargin )
+ {
+ if ( IsPropertyAutoL (*leftMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( remainingWidth / 2, 0 );
+ marginRect.Resize( remainingWidth, 0 );
+ borderRect.Move( remainingWidth / 2, 0 );
+ normalFlowBorderRect.Move( remainingWidth / 2, 0 );
+ paddingRect.Move( remainingWidth / 2, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ else
+ {
+ // only right margin set to AUTO
+ TInt remainingWidth = aWidthToFit - size.iWidth;
+ if ( remainingWidth < 0 )
+ {
+ remainingWidth = 0;
+ }
+ // move rect right to fill the void
+ marginRect.Resize( remainingWidth, 0 );
+ horizontalMarginProcessed = ETrue;
+ size = TSize( size.iWidth + remainingWidth,
+ size.iHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName == XnPropertyNames::style::common::KMarginTop )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is bottom margin also set to AUTO?
+ CXnProperty* bottomMargin = aNode.MarginBottomL();
+ if ( bottomMargin )
+ {
+ if ( IsPropertyAutoL( *bottomMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight / 2 );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, remainingHeight / 2 );
+ normalFlowBorderRect.Move( 0, remainingHeight / 2 );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only top margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ contentRect.Move( 0, remainingHeight );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, remainingHeight );
+ normalFlowBorderRect.Move( 0, remainingHeight );
+ paddingRect.Move( 0, remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+
+ if ( attributeName ==
+ XnPropertyNames::style::common::KMarginBottom )
+ {
+ if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
+ {
+ // is top margin also set to AUTO?
+ CXnProperty* topMargin = aNode.MarginTopL();
+ if ( topMargin )
+ {
+ if ( IsPropertyAutoL( *topMargin ) )
+ {
+ // both margins set to AUTO, values equal
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ TRect normalFlowBorderRect(
+ aNode.NormalFlowBorderRect() );
+ contentRect.Move( 0, remainingHeight / 2 );
+ marginRect.Resize( 0, remainingHeight );
+ borderRect.Move( 0, remainingHeight / 2 );
+ normalFlowBorderRect.Move( 0, remainingHeight / 2 );
+ paddingRect.Move( 0, remainingHeight / 2 );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ else
+ {
+ // only bottom margin set to AUTO
+ TInt remainingHeight = aHeightToFit - size.iHeight;
+ if ( remainingHeight < 0 )
+ {
+ remainingHeight = 0;
+ }
+ // move rect right to fill the void
+ marginRect.Resize( 0, remainingHeight );
+ verticalMarginProcessed = ETrue;
+ size = TSize( size.iWidth,
+ size.iHeight + remainingHeight );
+ }
+ }
+ }
+ }
+ }
+ }
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ return contentRect.Size();
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateAbsolutePositionsL()
+// Move the rect by it's absolute positioning.
+// -----------------------------------------------------------------------------
+//
+static void CalculateAbsolutePositionsL( CXnNode& aNode, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ CXnProperty* topProperty = aNode.TopL();
+ CXnProperty* bottomProperty = aNode.BottomL();
+ CXnProperty* leftProperty = aNode.LeftL();
+ CXnProperty* rightProperty = aNode.RightL();
+
+ TBool verticalValuesProcessed = EFalse;
+ TBool horizontalValuesProcessed = EFalse;
+
+ TInt top = 0;
+ TInt bottom = 0;
+ TInt left = 0;
+ TInt right = 0;
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+
+ if ( HasNodeAutoValuesL( aNode ) )
+ {
+ CXnProperty* marginTopProperty = aNode.MarginTopL();
+ CXnProperty* marginBottomProperty = aNode.MarginBottomL();
+ CXnProperty* marginLeftProperty = aNode.MarginLeftL();
+ CXnProperty* marginRightProperty = aNode.MarginRightL();
+ CXnProperty* heightProperty = aNode.HeightL();
+ CXnProperty* widthProperty = aNode.WidthL();
+ CXnProperty* maxHeightProperty = aNode.MaxHeightL();
+ CXnProperty* maxWidthProperty = aNode.MaxWidthL();
+ CXnProperty* minHeightProperty = aNode.MinHeightL();
+ CXnProperty* minWidthProperty = aNode.MinWidthL();
+
+ // move auto value node to it's parent's top left corner
+ TInt offsetx = 0;
+ TInt offsety = 0;
+
+ offsetx = aParentRect.iTl.iX - marginRect.iTl.iX;
+ offsety = aParentRect.iTl.iY - marginRect.iTl.iY;
+
+ contentRect.Move( offsetx, offsety );
+ paddingRect.Move( offsetx, offsety );
+ borderRect.Move( offsetx, offsety );
+ marginRect.Move( offsetx, offsety );
+
+ // get values
+ if ( topProperty && !IsPropertyAutoL( *topProperty ) &&
+ !IsPropertyNone( *topProperty ) )
+ {
+ top = VerticalPixelValueL( topProperty, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ if ( bottomProperty && !IsPropertyAutoL( *bottomProperty ) &&
+ !IsPropertyNone( *bottomProperty ) )
+ {
+ bottom = VerticalPixelValueL( bottomProperty, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ if ( leftProperty && !IsPropertyAutoL( *leftProperty ) &&
+ !IsPropertyNone( *leftProperty ) )
+ {
+ left = HorizontalPixelValueL( leftProperty, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ if ( rightProperty && !IsPropertyAutoL( *rightProperty ) &&
+ !IsPropertyNone( *rightProperty ) )
+ {
+ right = HorizontalPixelValueL( rightProperty, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ // node has auto values
+ TSize spaceUsed( CalculateTotalDimensionsL( aNode, EFalse, EFalse,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels ) );
+ TInt heightToUse =
+ aParentRect.Height() - spaceUsed.iHeight - top - bottom;
+ TInt widthToUse =
+ aParentRect.Width() - spaceUsed.iWidth - left - right;
+
+ if ( heightToUse < 0 )
+ {
+ heightToUse = 0;
+ }
+ if ( widthToUse < 0 )
+ {
+ widthToUse = 0;
+ }
+ // vertical auto values
+ // (margin top, margin bottom, height, top, bottom)
+ if ( IsPropertyAutoL( *heightProperty ) )
+ {
+ contentRect.Resize( 0, heightToUse );
+ paddingRect.Resize( 0, heightToUse );
+ borderRect.Resize( 0, heightToUse );
+ marginRect.Resize( 0, heightToUse );
+
+ if ( IsLargerThanMaxSizeL( aParentRect, aNode, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
+ {
+ if ( !IsPropertyNone( *maxHeightProperty ) )
+ {
+ TInt maxheight = HorizontalPixelValueL( maxHeightProperty,
+ aParentRect.Height(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ if ( maxheight < contentRect.Height() )
+ {
+ TInt excessheight = contentRect.Height() - maxheight;
+ contentRect.Resize( 0, -excessheight );
+ paddingRect.Resize( 0, -excessheight );
+ borderRect.Resize( 0, -excessheight );
+ marginRect.Resize( 0, -excessheight );
+ }
+ }
+ }
+ if ( IsSmallerThanMinSizeL( aParentRect, aNode, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
+ {
+ if ( !IsPropertyNone( *minHeightProperty ) )
+ {
+ TInt minheight = HorizontalPixelValueL( minHeightProperty,
+ aParentRect.Height(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ if ( minheight > contentRect.Height() )
+ {
+ TInt missingheight = minheight - contentRect.Height();
+ contentRect.Resize( 0, missingheight );
+ paddingRect.Resize( 0, missingheight );
+ borderRect.Resize( 0, missingheight );
+ marginRect.Resize( 0, missingheight );
+ }
+ }
+ }
+ verticalValuesProcessed = ETrue;
+ }
+
+ if ( !verticalValuesProcessed )
+ {
+ if ( IsPropertyAutoL( *topProperty ) &&
+ IsPropertyAutoL( *bottomProperty ) )
+ {
+ // move the box down
+ contentRect.Move( 0, heightToUse / 2 );
+ paddingRect.Move( 0, heightToUse / 2 );
+ borderRect.Move( 0, heightToUse / 2 );
+ marginRect.Move( 0, heightToUse / 2 );
+ }
+ if ( IsPropertyAutoL( *topProperty ) &&
+ !IsPropertyAutoL( *bottomProperty ) )
+ {
+ // move the box down
+ contentRect.Move( 0, heightToUse );
+ paddingRect.Move( 0, heightToUse );
+ borderRect.Move( 0, heightToUse );
+ marginRect.Move( 0, heightToUse );
+ }
+ if ( IsPropertyAutoL( *marginTopProperty ) &&
+ IsPropertyAutoL( *marginBottomProperty ) )
+ {
+ // both margins auto, equal values
+ marginRect.Resize( 0, heightToUse );
+ paddingRect.Move( 0, heightToUse / 2 );
+ borderRect.Move( 0, heightToUse / 2 );
+ contentRect.Move( 0, heightToUse / 2 );
+ }
+ if ( !IsPropertyAutoL( *marginTopProperty ) &&
+ IsPropertyAutoL( *marginBottomProperty ) )
+ {
+ // only top margin auto
+ marginRect.Resize( 0, heightToUse );
+ paddingRect.Move( 0, heightToUse );
+ borderRect.Move( 0, heightToUse );
+ contentRect.Move( 0, heightToUse );
+ }
+ if ( IsPropertyAutoL( *marginTopProperty ) &&
+ !IsPropertyAutoL( *marginBottomProperty ) )
+ {
+ // only bottom margin auto
+ marginRect.Resize( 0, heightToUse );
+ }
+ }
+
+ // horizontal auto values
+ // (margin left, margin right, width)
+ if ( IsPropertyAutoL( *widthProperty ) )
+ {
+ contentRect.Resize( widthToUse, 0 );
+ paddingRect.Resize( widthToUse, 0 );;
+ borderRect.Resize( widthToUse, 0 );
+ marginRect.Resize( widthToUse, 0 );
+ if ( IsLargerThanMaxSizeL( aParentRect, aNode, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
+ {
+ if ( !IsPropertyNone( *maxWidthProperty ) )
+ {
+ TInt maxwidth = HorizontalPixelValueL( maxWidthProperty,
+ aParentRect.Width(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ if ( maxwidth < contentRect.Width() )
+ {
+ TInt excesswidth = contentRect.Width() - maxwidth;
+ contentRect.Resize( -excesswidth, 0 );
+ paddingRect.Resize( -excesswidth, 0 );
+ borderRect.Resize( -excesswidth, 0 );
+ marginRect.Resize( -excesswidth, 0 );
+ }
+ }
+ }
+ if ( IsSmallerThanMinSizeL( aParentRect, aNode, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
+ {
+ if ( !IsPropertyNone( *minWidthProperty ) )
+ {
+ TInt minwidth = HorizontalPixelValueL( minWidthProperty,
+ aParentRect.Width(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ if ( minwidth > contentRect.Width() )
+ {
+ TInt missingwidth = minwidth - contentRect.Width();
+ contentRect.Resize( missingwidth, 0 );
+ paddingRect.Resize( missingwidth, 0 );
+ borderRect.Resize( missingwidth, 0 );
+ marginRect.Resize( missingwidth, 0 );
+ }
+ }
+ }
+ horizontalValuesProcessed = ETrue;
+ }
+ if ( !horizontalValuesProcessed )
+ {
+ if ( IsPropertyAutoL( *leftProperty ) &&
+ IsPropertyAutoL( *rightProperty ) )
+ {
+ // move the box left
+ contentRect.Move( widthToUse / 2, 0 );
+ paddingRect.Move( widthToUse / 2, 0 );
+ borderRect.Move( widthToUse / 2, 0 );
+ marginRect.Move( widthToUse / 2, 0 );
+ }
+ if ( IsPropertyAutoL( *leftProperty ) &&
+ !IsPropertyAutoL( *rightProperty ) )
+ {
+ // move the box left
+ contentRect.Move( widthToUse, 0 );
+ paddingRect.Move( widthToUse, 0 );
+ borderRect.Move( widthToUse, 0 );
+ marginRect.Move( widthToUse, 0 );
+ }
+ if ( IsPropertyAutoL( *marginLeftProperty ) &&
+ IsPropertyAutoL( *marginRightProperty ) )
+ {
+ // both margins auto, equal values
+ marginRect.Resize( widthToUse, 0 );
+ paddingRect.Move( widthToUse / 2, 0 );
+ borderRect.Move( widthToUse / 2, 0 );
+ contentRect.Move( widthToUse / 2, 0 );
+ }
+ if ( !IsPropertyAutoL( *marginLeftProperty ) &&
+ IsPropertyAutoL( *marginRightProperty ) )
+ {
+ // only right margin auto
+ marginRect.Resize( widthToUse, 0 );
+ paddingRect.Move( widthToUse, 0 );
+ borderRect.Move( widthToUse, 0 );
+ contentRect.Move( widthToUse, 0 );
+ }
+ if ( IsPropertyAutoL( *marginLeftProperty ) &&
+ !IsPropertyAutoL( *marginRightProperty ) )
+ {
+ // only left margin auto
+ marginRect.Resize( widthToUse, 0 );
+ }
+ }
+ }
+
+ // Move the rect to desired position
+ if ( topProperty )
+ {
+ if ( !IsPropertyAutoL( *topProperty ) &&
+ !IsPropertyNone( *topProperty ) )
+ {
+ TInt y = VerticalPixelValueL( topProperty, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ contentRect.Move( 0, y );
+ paddingRect.Move( 0, y );
+ borderRect.Move( 0, y );
+ marginRect.Move( 0, y );
+ }
+ }
+ if ( leftProperty )
+ {
+ if ( !IsPropertyAutoL( *leftProperty ) &&
+ !IsPropertyNone( *leftProperty ) )
+ {
+ TInt x = HorizontalPixelValueL( leftProperty, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ contentRect.Move( x, 0 );
+ paddingRect.Move( x, 0 );
+ borderRect.Move( x, 0 );
+ marginRect.Move( x, 0 );
+ }
+ }
+ if ( bottomProperty )
+ {
+ if ( !IsPropertyAutoL( *bottomProperty ) &&
+ !IsPropertyNone( *bottomProperty ) )
+ {
+ TInt py = VerticalPixelValueL( bottomProperty,
+ aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
+ contentRect.Move( 0, -py );
+ paddingRect.Move( 0, -py );
+ borderRect.Move( 0, -py );
+ marginRect.Move( 0, -py );
+ }
+ }
+ if ( rightProperty )
+ {
+ if ( !IsPropertyAutoL( *rightProperty ) &&
+ !IsPropertyNone( *rightProperty ) )
+ {
+ TInt px = HorizontalPixelValueL( rightProperty,
+ aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
+ contentRect.Move( -px, 0 );
+ paddingRect.Move( -px, 0 );
+ borderRect.Move( -px, 0 );
+ marginRect.Move( -px, 0 );
+ }
+ }
+
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+
+ DropExceedingRectL( aParentRect, aNode );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateBorderL()
+// Move the rect by adding the border.
+// -----------------------------------------------------------------------------
+//
+static void CalculateBorderL( CXnNode& aNode, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TInt offsetx = 0;
+ TInt offsety = 0;
+
+ TInt borderleft = 0;
+ TInt borderright = 0;
+ TInt bordertop = 0;
+ TInt borderbottom = 0;
+
+ CXnProperty* commonBorderStyle = aNode.BorderStyleL();
+ CXnProperty* borderImage = aNode.BorderImageL();
+ CXnProperty* borderStyle = aNode.BorderLeftStyleL();
+ CXnProperty* borderproperty = aNode.BorderLeftL();
+
+ // if border width is defined
+ CXnProperty* borderwidthproperty = aNode.BorderWidthL();
+ if ( !borderproperty )
+ {
+ borderproperty = borderwidthproperty;
+ }
+
+ if ( borderwidthproperty && ( ( commonBorderStyle &&
+ !IsPropertyNone( *commonBorderStyle ) ) ||
+ ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
+ {
+ TInt bordervertical = 0;
+ TInt borderhorizontal = 0;
+
+ DetermineBorderWidthsL( borderwidthproperty, bordervertical,
+ borderhorizontal, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+
+ borderleft = borderhorizontal;
+ borderright = borderhorizontal;
+ bordertop = bordervertical;
+ borderbottom = bordervertical;
+ }
+
+ TInt ignore;
+ // use border width only if there is valid border style or border image
+ if ( borderproperty && ( ( borderStyle &&
+ !IsPropertyNone( *borderStyle ) ) ||
+ ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
+ ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
+ {
+ DetermineBorderWidthsL( borderproperty, ignore, borderleft,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ borderStyle = aNode.BorderRightStyleL();
+ borderproperty = aNode.BorderRightL();
+ if ( !borderproperty )
+ {
+ borderproperty = borderwidthproperty;
+ }
+ if ( borderproperty && ( ( borderStyle &&
+ !IsPropertyNone( *borderStyle ) ) ||
+ ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
+ ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
+ {
+ DetermineBorderWidthsL( borderproperty, ignore, borderright,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ borderStyle = aNode.BorderTopStyleL();
+ borderproperty = aNode.BorderTopL();
+ if ( !borderproperty )
+ {
+ borderproperty = borderwidthproperty;
+ }
+ if ( borderproperty && ( ( borderStyle &&
+ !IsPropertyNone( *borderStyle ) ) ||
+ ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
+ ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
+ {
+ DetermineBorderWidthsL( borderproperty, bordertop, ignore,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ borderStyle = aNode.BorderBottomStyleL();
+ borderproperty = aNode.BorderBottomL();
+ if ( !borderproperty )
+ {
+ borderproperty = borderwidthproperty;
+ }
+ if ( borderproperty && ( ( borderStyle &&
+ !IsPropertyNone( *borderStyle ) ) ||
+ ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
+ ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
+ {
+ DetermineBorderWidthsL( borderproperty, borderbottom, ignore,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+
+ offsetx = borderleft; // move the client rect of the element this much right
+ offsety = bordertop; // move the client rect of the element this much down
+
+ TRect newrect( aNode.Rect() );
+ newrect.Move( offsetx, offsety );
+ aNode.SetRect( newrect );
+ // and move the padding rect also, Ari 5.8.2005
+ TRect paddingrect = aNode.PaddingRect();
+ TPoint origin( paddingrect.iTl );
+ paddingrect.Move( offsetx, offsety );
+ aNode.SetPaddingRect( paddingrect );
+
+ TRect borderrect( origin, TSize(
+ borderleft + borderright + paddingrect.Width(),
+ bordertop + borderbottom + paddingrect.Height() ) );
+ TRect normalFlowBorderRect( origin, TSize(
+ borderleft + borderright + paddingrect.Width(),
+ bordertop + borderbottom + paddingrect.Height() ) );
+ aNode.SetBorderRect( borderrect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateAbsoluteMarginL()
+// Place child areas to parent rect and calculate margins.
+// -----------------------------------------------------------------------------
+//
+static void CalculateAbsoluteMarginL( CXnNode& aParent, CXnNode& aNode,
+ CXnNode* aPreviousSibling, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TInt previousPosition = 0;
+ CXnProperty* marginProperty = NULL;
+ TInt marginLeft = 0;
+ TInt marginRight = 0;
+ TInt marginTop = 0;
+ TInt marginBottom = 0;
+
+ marginProperty = aNode.MarginLeftL();
+
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginLeft = HorizontalPixelValueL( marginProperty,
+ aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+
+ marginProperty = aNode.MarginRightL();
+
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginRight = HorizontalPixelValueL( marginProperty,
+ aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+
+ marginProperty = aNode.MarginTopL();
+
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginTop = VerticalPixelValueL( marginProperty,
+ aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+
+ marginProperty = aNode.MarginBottomL();
+
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginBottom = VerticalPixelValueL( marginProperty,
+ aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+
+ TInt offsetx = 0;
+ TInt offsety = 0;
+
+ if ( &aParent == &aNode )
+ {
+ aParentRect.Move( -aParentRect.iTl.iX, -aParentRect.iTl.iY );
+ }
+
+ // if all properties are defined and block progression is LR, margin right
+ // is ignored and replaced by remaining
+ // if block progression is RL, same thing to margin left
+
+ // previous sibling was found, get it's margin and previous coordinate to
+ // define next child's position
+ previousPosition = ( aPreviousSibling != NULL ) ?
+ GetPositionL( *aPreviousSibling, aParentBlockProgression,
+ aParentDirection ) : 0;
+
+ // Move the rect considering previous child
+ // Margins are collapsed, larger is used
+ if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ // offset to parent rect's top left corner
+ if ( !aPreviousSibling )
+ {
+ offsetx = aParentRect.iTl.iX;
+ }
+
+ offsety = aParentRect.iTl.iY + marginTop;
+ TInt prevMarginRight = 0;
+
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ prevMarginRight =
+ previousMarginRect.iBr.iX - previousBorderRect.iBr.iX;
+ }
+
+ if ( prevMarginRight > marginLeft )
+ {
+ offsetx += previousPosition + prevMarginRight;
+ }
+ else
+ {
+ offsetx += previousPosition + marginLeft;
+ }
+ }
+ else // TB or BT
+ {
+ // offset to parent rect's top left corner
+ offsetx = aParentRect.iTl.iX + marginLeft;
+
+ if ( !aPreviousSibling )
+ {
+ offsety = aParentRect.iTl.iY;
+ }
+
+ TInt prevMarginBottom = 0;
+
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ prevMarginBottom =
+ previousMarginRect.iBr.iY - previousBorderRect.iBr.iY;
+ }
+
+ if ( prevMarginBottom > marginTop )
+ {
+ offsety += previousPosition + prevMarginBottom;
+ }
+ else
+ {
+ offsety += previousPosition + marginTop;
+ }
+ }
+ }
+ else // RTL
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ // offset to parent rect's top right corner
+ if ( !aPreviousSibling )
+ {
+ offsetx = aParentRect.Width() - aNode.BorderRect().Width() +
+ aParentRect.iTl.iX;
+ }
+ else
+ {
+ offsetx = previousPosition - aNode.BorderRect().Width();
+ }
+
+ offsety = aParentRect.iTl.iY + marginTop;
+
+ TInt prevMarginLeft = 0;
+
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ prevMarginLeft =
+ previousBorderRect.iTl.iX - previousMarginRect.iTl.iX;
+ }
+
+ if ( prevMarginLeft > marginRight )
+ {
+ offsetx -= prevMarginLeft;
+ }
+ else
+ {
+ offsetx -= marginRight;
+ }
+ }
+ else // TB or BT
+ {
+ // offset to parent rect's bottom left corner
+ offsetx += aParentRect.iTl.iX + marginRight;
+
+ if ( !aPreviousSibling )
+ {
+ // start from bottom of parent rect
+ offsety = aParentRect.Height() - aNode.BorderRect().Height();
+ }
+ else
+ {
+ offsety = previousPosition - aNode.BorderRect().Height();
+ }
+
+ TInt prevMarginTop = 0;
+
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ prevMarginTop =
+ previousBorderRect.iTl.iY - previousMarginRect.iTl.iY;
+ }
+
+ // collapse margins
+ if ( prevMarginTop > marginBottom )
+ {
+ offsety -= prevMarginTop;
+ }
+ else
+ {
+ offsety -= marginBottom;
+ }
+ }
+ }
+
+ TRect borderRect = TRect( aNode.BorderRect() );
+ TRect normalFlowBorderRect = TRect( aNode.NormalFlowBorderRect() );
+ // this is the top left corner of margin rect
+ TPoint origin( borderRect.iTl - TPoint( marginLeft, marginTop ) );
+
+ if ( &aParent != &aNode )
+ {
+ // set content rect
+ TRect newRect( aNode.Rect() );
+ newRect.Move( offsetx, offsety );
+ aNode.SetRect( newRect );
+
+ // set padding rect
+ TRect paddingRect( aNode.PaddingRect() );
+ paddingRect.Move( offsetx, offsety );
+ aNode.SetPaddingRect( paddingRect );
+
+ // set border rect
+ borderRect.Move( offsetx, offsety );
+ normalFlowBorderRect.Move( offsetx, offsety );
+ // this is the top left corner of margin rect
+ origin = TPoint( borderRect.iTl - TPoint( marginLeft, marginTop ) );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ }
+
+ TRect marginRect( origin,
+ TSize( marginLeft + marginRight + borderRect.Width(),
+ marginTop + marginBottom + borderRect.Height() ) );
+
+ aNode.SetMarginRect( marginRect );
+
+ // Within this function, the rects are adjusted if the display-priority is 0
+ // and margin rect exceeds parent's content rect.
+ DropExceedingRectL( aParentRect, aNode );
+
+ if( IsNodeTooltip( aNode ) || aNode.Type()->Type() == KWidgetExtensionNodeName ||
+ aNode.Type()->Type() == KPopUpNodeName )
+ {
+ // because tooltip has it's own window, move margin rect to 0,0
+ // and all other rects as much up left
+ TRect marginRect = aNode.MarginRect();
+
+ TRect borderRect = aNode.BorderRect();
+ TRect paddingRect = aNode.PaddingRect();
+ TRect contentRect = aNode.Rect();
+ TInt x = marginRect.iTl.iX;
+ TInt y = marginRect.iTl.iY;
+ marginRect.Move( -x, -y );
+
+ borderRect.Move( -x, -y );
+ paddingRect.Move( -x, -y );
+ contentRect.Move( -x, -y );
+
+ aNode.SetMarginRect( marginRect );
+
+ aNode.SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetRect( contentRect );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateAbsoluteMarginL()
+// Place child areas to parent rect and calculate margins.
+// -----------------------------------------------------------------------------
+//
+static void CalculateMarginL( CXnNode& aParent, CXnNode& aNode,
+ CXnNode* aPreviousSibling, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels, TInt& aColumnWidth, TInt& aColumnMargin )
+ {
+ if( aParent.Control() && aParent.Control()->OwnsWindow() )
+ {
+ aParentRect = TRect( aParentRect.iTl - aParent.MarginRect().iTl, aParentRect.Size() );
+ }
+
+ CXnProperty* marginProperty = NULL;
+ TInt marginLeft = 0;
+ TInt marginRight = 0;
+ TInt marginTop = 0;
+ TInt marginBottom = 0;
+
+ marginProperty = aNode.MarginLeftL();
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginLeft = HorizontalPixelValueL(
+ marginProperty, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+
+ marginProperty = aNode.MarginRightL();
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginRight = HorizontalPixelValueL(
+ marginProperty, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+
+ marginProperty = aNode.MarginTopL();
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginTop = VerticalPixelValueL(
+ marginProperty, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+
+ marginProperty = aNode.MarginBottomL();
+ if ( marginProperty )
+ {
+ if ( !IsPropertyAutoL( *marginProperty ) )
+ {
+ marginBottom = VerticalPixelValueL(
+ marginProperty, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+
+ TInt offsetx = 0;
+ TInt offsety = 0;
+
+ //What's this???
+ if ( &aParent == &aNode )
+ {
+ aParentRect.Move( -aParentRect.iTl.iX, -aParentRect.iTl.iY );
+ }
+
+ // Move the rect considering previous child
+ // Margins are collapsed, larger is used
+ if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
+ {
+ // LTR , TB
+ // *********
+ // | 1 | 4 |
+ // | 2 | 5 |
+ // | 3 | 6 |
+ // *********
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB )
+ {
+ // First we need to know where to layout next sibling
+ // Try first under the previous sibling...
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutUnderPrevious( EFalse );
+ TInt height = aNode.MarginRect().Height();
+ TInt prevMarginBottom =
+ previousMarginRect.iBr.iY - previousBorderRect.iBr.iY;
+ if ( prevMarginBottom < marginTop )
+ {
+ height -= prevMarginBottom;
+ }
+ else
+ {
+ height -= marginTop;
+ }
+ if(height <= aParentRect.iBr.iY - previousMarginRect.iBr.iY || IsSrollableBox(aNode))
+ {
+ layoutUnderPrevious = ETrue;
+ }
+
+ // ...then to the next column
+ if ( !layoutUnderPrevious )
+ {
+ TInt width =
+ aNode.BorderRect().Width() + marginLeft + marginRight;
+ if ( aColumnMargin < marginLeft )
+ {
+ width -= aColumnMargin;
+ }
+ else
+ {
+ width -= marginLeft;
+ }
+ if ( width + aColumnWidth <= aParentRect.Width() )
+ {
+ offsety = aParentRect.iTl.iY + marginTop;
+ if ( aColumnMargin < marginLeft )
+ {
+ offsetx = aParentRect.iTl.iX + aColumnWidth -
+ aColumnMargin + marginLeft;
+ }
+ else
+ {
+ offsetx = aParentRect.iTl.iX + aColumnWidth;
+ }
+ }
+ else
+ {
+ layoutUnderPrevious = ETrue;
+ }
+ }
+ if ( layoutUnderPrevious )
+ {
+ offsetx =
+ aPreviousSibling->MarginRect().iTl.iX + marginLeft;
+ if ( prevMarginBottom > marginTop )
+ {
+ // margin of this node is collapsed
+ offsety = previousMarginRect.iBr.iY;
+ }
+ else
+ {
+ // margin of the previous node is collapsed
+ offsety = previousBorderRect.iBr.iY + marginTop;
+ }
+ }
+ }
+ else
+ {
+ // offset to parent rect's top left corner
+ offsetx = aParentRect.iTl.iX + marginLeft;
+ offsety = aParentRect.iTl.iY + marginTop;
+ }
+ }
+
+ // LTR , BT
+ // *********
+ // | 3 | 6 |
+ // | 2 | 5 |
+ // | 1 | 4 |
+ // *********
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ // First we need to know where to layout next sibling
+ // Try first above the previous sibling...
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutAbovePrevious( EFalse );
+ TInt height =
+ aNode.BorderRect().Height() + marginTop + marginBottom;
+ TInt prevMarginTop =
+ previousBorderRect.iTl.iY - previousMarginRect.iTl.iY;
+ if ( prevMarginTop < marginBottom )
+ {
+ height -= prevMarginTop;
+ }
+ else
+ {
+ height -= marginBottom;
+ }
+ if ( height <= previousMarginRect.iTl.iY - aParentRect.iTl.iY )
+ {
+ layoutAbovePrevious = ETrue;
+ }
+
+ // ...then to the next column
+ if ( !layoutAbovePrevious )
+ {
+ TInt width =
+ aNode.BorderRect().Width() + marginLeft + marginRight;
+ if ( aColumnMargin < marginLeft )
+ {
+ width -= aColumnMargin;
+ }
+ else
+ {
+ width -= marginLeft;
+ }
+ if ( width + aColumnWidth <= aParentRect.Width() )
+ {
+ offsety = aParentRect.iBr.iY - marginBottom -
+ aNode.BorderRect().Height();
+ if ( aColumnMargin < marginLeft )
+ {
+ offsetx = aParentRect.iTl.iX + aColumnWidth -
+ aColumnMargin + marginLeft;
+ }
+ else
+ {
+ offsetx = aParentRect.iTl.iX + aColumnWidth;
+ }
+ }
+ else
+ {
+ layoutAbovePrevious = ETrue;
+ }
+ }
+ if ( layoutAbovePrevious )
+ {
+ offsetx =
+ aPreviousSibling->MarginRect().iTl.iX + marginLeft;
+ if ( prevMarginTop > marginBottom )
+ {
+ // margin of this node is collapsed
+ offsety = previousMarginRect.iTl.iY -
+ aNode.BorderRect().Height();
+ }
+ else
+ {
+ // margin of the previous node is collapsed
+ offsety = previousBorderRect.iTl.iY - marginBottom -
+ aNode.BorderRect().Height();
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iTl.iX + marginLeft;
+ offsety = aParentRect.iBr.iY - marginBottom -
+ aNode.BorderRect().Height();
+ }
+ }
+
+ // LTR , LR
+ // *********
+ // | 5 | 6 |
+ // | 3 | 4 |
+ // | 1 | 2 |
+ // *********
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR )
+ {
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutNextToPrevious( EFalse );
+ TInt width =
+ aNode.BorderRect().Width() + marginRight + marginLeft;
+ TInt prevMarginRight =
+ previousMarginRect.iBr.iX - previousBorderRect.iBr.iX;
+ if ( prevMarginRight < marginLeft )
+ {
+ width -= prevMarginRight;
+ }
+ else
+ {
+ width -= marginLeft;
+ }
+ if ( width <= aParentRect.iBr.iX - previousMarginRect.iBr.iX )
+ {
+ layoutNextToPrevious = ETrue;
+ }
+
+ if ( !layoutNextToPrevious )
+ {
+ TInt height = aNode.BorderRect().Height() + marginTop +
+ marginBottom;
+ if ( aColumnMargin < marginBottom )
+ {
+ height -= aColumnMargin;
+ }
+ else
+ {
+ height -= marginBottom;
+ }
+ if ( height + aColumnWidth <= aParentRect.Height() )
+ {
+ offsetx = aParentRect.iTl.iX + marginLeft;
+ if ( aColumnMargin < marginTop )
+ {
+ offsety = aParentRect.iBr.iY - aColumnWidth +
+ aColumnMargin - aNode.BorderRect().Height() -
+ marginBottom;
+ }
+ else
+ {
+ offsety = aParentRect.iBr.iY - aColumnWidth -
+ aNode.BorderRect().Height();
+ }
+ }
+ else
+ {
+ layoutNextToPrevious = ETrue;
+ }
+ }
+ if ( layoutNextToPrevious )
+ {
+ offsety = aPreviousSibling->MarginRect().iBr.iY -
+ aNode.BorderRect().Height() - marginBottom;
+ if ( prevMarginRight > marginLeft )
+ {
+ // margin of this node is collapsed
+ offsetx = previousMarginRect.iBr.iX;
+ }
+ else
+ {
+ // margin of the previous node is collapsed
+ offsetx = previousBorderRect.iBr.iX + marginLeft;
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iTl.iX + marginLeft;
+ offsety = aParentRect.iBr.iY - aNode.BorderRect().Height() -
+ marginBottom;
+ }
+ }
+
+ // LTR , RL
+ // *********
+ // | 1 | 2 |
+ // | 3 | 4 |
+ // | 5 | 6 |
+ // *********
+
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutNextToPrevious( EFalse );
+ TInt width =
+ aNode.BorderRect().Width() + marginRight + marginLeft;
+ TInt prevMarginRight =
+ previousMarginRect.iBr.iX - previousBorderRect.iBr.iX;
+ if ( prevMarginRight < marginLeft )
+ {
+ width -= prevMarginRight;
+ }
+ else
+ {
+ width -= marginLeft;
+ }
+ if ( width <= aParentRect.iBr.iX - previousMarginRect.iBr.iX )
+ {
+ layoutNextToPrevious = ETrue;
+ }
+
+ if ( !layoutNextToPrevious )
+ {
+ TInt height =
+ aNode.BorderRect().Height() + marginTop + marginBottom;
+ if ( aColumnMargin < marginTop )
+ {
+ height -= aColumnMargin;
+ }
+ else
+ {
+ height -= marginTop;
+ }
+ if ( height + aColumnWidth <= aParentRect.Height() )
+ {
+ offsetx = aParentRect.iTl.iX + marginLeft;
+ if ( aColumnMargin < marginTop )
+ {
+ offsety = aParentRect.iTl.iY + aColumnWidth -
+ aColumnMargin + marginTop;
+ }
+ else
+ {
+ offsety = aParentRect.iTl.iY + aColumnWidth;
+ }
+ }
+ else
+ {
+ layoutNextToPrevious = ETrue;
+ }
+ }
+ if ( layoutNextToPrevious )
+ {
+ offsety = aPreviousSibling->MarginRect().iTl.iY + marginTop;
+ if ( prevMarginRight > marginLeft )
+ {
+ // margin of this node is collapsed
+ offsetx = previousMarginRect.iBr.iX;
+ }
+ else
+ {
+ // margin of the previous node is collapsed
+ offsetx = previousBorderRect.iBr.iX + marginLeft;
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iTl.iX + marginLeft;
+ offsety = aParentRect.iTl.iY + marginTop;
+ }
+ }
+ }
+
+ else
+ {
+ // RTL , TB
+ // *********
+ // | 4 | 1 |
+ // | 5 | 2 |
+ // | 6 | 3 |
+ // *********
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB )
+ {
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutUnderPrevious( EFalse );
+ TInt height = aNode.MarginRect().Height();
+ TInt prevMarginBottom =
+ previousMarginRect.iBr.iY - previousBorderRect.iBr.iY;
+ if ( prevMarginBottom < marginTop )
+ {
+ height -= prevMarginBottom;
+ }
+ else
+ {
+ height -= marginTop;
+ }
+ if ( height <= aParentRect.iBr.iY - previousMarginRect.iBr.iY )
+ {
+ layoutUnderPrevious = ETrue;
+ }
+
+ if ( !layoutUnderPrevious )
+ {
+ TInt width =
+ aNode.BorderRect().Width() + marginLeft + marginRight;
+ if ( aColumnMargin < marginLeft )
+ {
+ width -= aColumnMargin;
+ }
+ else
+ {
+ width -= marginLeft;
+ }
+ if ( width + aColumnWidth <= aParentRect.Width() )
+ {
+ offsety = aParentRect.iTl.iY + marginTop;
+ if ( aColumnMargin < marginLeft )
+ {
+ offsetx = aParentRect.iBr.iX - aColumnWidth +
+ aColumnMargin - marginRight -
+ aNode.BorderRect().Width();
+ }
+ else
+ {
+ offsetx = aParentRect.iBr.iX - aColumnWidth -
+ aNode.BorderRect().Width();
+ }
+ }
+ else
+ {
+ layoutUnderPrevious = ETrue;
+ }
+ }
+ if ( layoutUnderPrevious )
+ {
+ offsetx = aPreviousSibling->MarginRect().iBr.iX -
+ marginRight - aNode.BorderRect().Width();
+ if ( prevMarginBottom > marginTop )
+ {
+ offsety = previousMarginRect.iBr.iY;
+ }
+ else
+ {
+ offsety = previousBorderRect.iBr.iY + marginTop;
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iBr.iX - marginRight -
+ aNode.BorderRect().Width();
+ offsety = aParentRect.iTl.iY + marginTop;
+ }
+ }
+
+ // RTL , BT
+ // *********
+ // | 6 | 3 |
+ // | 5 | 2 |
+ // | 4 | 1 |
+ // *********
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutAbovePrevious( EFalse );
+ TInt height =
+ aNode.BorderRect().Height() + marginTop + marginBottom;
+ TInt prevMarginTop =
+ previousBorderRect.iTl.iY - previousMarginRect.iTl.iY;
+ if ( prevMarginTop < marginBottom )
+ {
+ height -= prevMarginTop;
+ }
+ else
+ {
+ height -= marginBottom;
+ }
+ if ( height <= previousMarginRect.iTl.iY - aParentRect.iTl.iY )
+ {
+ layoutAbovePrevious = ETrue;
+ }
+
+ if ( !layoutAbovePrevious )
+ {
+ TInt width =
+ aNode.BorderRect().Width() + marginLeft + marginRight;
+ if ( aColumnMargin < marginRight )
+ {
+ width -= aColumnMargin;
+ }
+ else
+ {
+ width -= marginRight;
+ }
+ if ( width + aColumnWidth <= aParentRect.Width() )
+ {
+ offsety = aParentRect.iBr.iY - marginBottom -
+ aNode.BorderRect().Height();
+ if ( aColumnMargin < marginLeft )
+ {
+ offsetx = aParentRect.iBr.iX - aColumnWidth +
+ aColumnMargin - marginRight -
+ aNode.BorderRect().Width();
+ }
+ else
+ {
+ offsetx = aParentRect.iBr.iX - aColumnWidth -
+ aNode.BorderRect().Width();
+ }
+ }
+ else
+ {
+ layoutAbovePrevious = ETrue;
+ }
+ }
+ if ( layoutAbovePrevious )
+ {
+ offsetx = aPreviousSibling->MarginRect().iBr.iX -
+ marginRight - aNode.BorderRect().Width();
+ if ( prevMarginTop > marginBottom )
+ {
+ // margin of this node is collapsed
+ offsety = previousMarginRect.iTl.iY -
+ aNode.BorderRect().Height();
+ }
+ else
+ {
+ // margin of the previous node is collapsed
+ offsety = previousBorderRect.iTl.iY - marginBottom -
+ aNode.BorderRect().Height();
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iBr.iX - marginRight -
+ aNode.BorderRect().Width();
+ offsety = aParentRect.iBr.iY - marginBottom -
+ aNode.BorderRect().Height();
+ }
+ }
+
+ // RTL , LR
+ // *********
+ // | 6 | 5 |
+ // | 4 | 3 |
+ // | 2 | 1 |
+ // *********
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR )
+ {
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutNextToPrevious( EFalse );
+ TInt width =
+ aNode.BorderRect().Width() + marginRight + marginLeft;
+ TInt prevMarginLeft =
+ previousBorderRect.iTl.iX - previousMarginRect.iTl.iX;
+ if ( prevMarginLeft < marginRight )
+ {
+ width -= prevMarginLeft;
+ }
+ else
+ {
+ width -= marginRight;
+ }
+ if ( width <= previousMarginRect.iTl.iX - aParentRect.iTl.iX )
+ {
+ layoutNextToPrevious = ETrue;
+ }
+
+ if ( !layoutNextToPrevious )
+ {
+ TInt height =
+ aNode.BorderRect().Height() + marginTop + marginBottom;
+ if ( aColumnMargin < marginBottom )
+ {
+ height -= aColumnMargin;
+ }
+ else
+ {
+ height -= marginBottom;
+ }
+ if ( height + aColumnWidth <= aParentRect.Height() )
+ {
+ offsetx = aParentRect.iBr.iX - marginRight -
+ aNode.BorderRect().Width();
+ if ( aColumnMargin < marginTop )
+ {
+ offsety = aParentRect.iBr.iY - aColumnWidth +
+ aColumnMargin - aNode.BorderRect().Height() -
+ marginBottom;
+ }
+ else
+ {
+ offsety = aParentRect.iBr.iY - aColumnWidth -
+ aNode.BorderRect().Height();
+ }
+ }
+ else
+ {
+ layoutNextToPrevious = ETrue;
+ }
+ }
+ if ( layoutNextToPrevious )
+ {
+ offsety = aPreviousSibling->MarginRect().iBr.iY -
+ aNode.BorderRect().Height() - marginBottom;
+ if ( prevMarginLeft > marginRight )
+ {
+ offsetx = previousMarginRect.iTl.iX -
+ aNode.BorderRect().Width();
+ }
+ else
+ {
+ offsetx = previousBorderRect.iTl.iX - marginRight -
+ aNode.BorderRect().Width();
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iBr.iX - marginRight -
+ aNode.BorderRect().Width();
+ offsety = aParentRect.iBr.iY - marginBottom -
+ aNode.BorderRect().Height();
+ }
+ }
+
+ // RTL , RL
+ // *********
+ // | 2 | 1 |
+ // | 4 | 3 |
+ // | 6 | 5 |
+ // *********
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ if ( aPreviousSibling )
+ {
+ TRect previousMarginRect = aPreviousSibling->MarginRect();
+ TRect previousBorderRect = aPreviousSibling->BorderRect();
+ TBool layoutNextToPrevious( EFalse );
+ TInt width =
+ aNode.BorderRect().Width() + marginRight + marginLeft;
+ TInt prevMarginLeft =
+ previousBorderRect.iTl.iX - previousMarginRect.iTl.iX;
+ if ( prevMarginLeft < marginRight )
+ {
+ width -= prevMarginLeft;
+ }
+ else
+ {
+ width -= marginRight;
+ }
+ if ( width <= previousMarginRect.iTl.iX - aParentRect.iTl.iX )
+ {
+ layoutNextToPrevious = ETrue;
+ }
+ if ( !layoutNextToPrevious )
+ {
+ TInt height =
+ aNode.BorderRect().Height() + marginTop + marginBottom;
+ if ( aColumnMargin < marginTop )
+ {
+ height -= aColumnMargin;
+ }
+ else
+ {
+ height -= marginTop;
+ }
+ if ( height + aColumnWidth <= aParentRect.Height() )
+ {
+ offsetx = aParentRect.iBr.iX - marginRight -
+ aNode.BorderRect().Width();
+ if ( aColumnMargin < marginTop )
+ {
+ offsety = aParentRect.iTl.iY + aColumnWidth -
+ aColumnMargin + marginTop;
+ }
+ else
+ {
+ offsety = aParentRect.iTl.iY + aColumnWidth;
+ }
+ }
+ else
+ {
+ layoutNextToPrevious = ETrue;
+ }
+ }
+ if ( layoutNextToPrevious )
+ {
+ offsety = aPreviousSibling->MarginRect().iTl.iY + marginTop;
+ if ( prevMarginLeft > marginRight )
+ {
+ offsetx = previousMarginRect.iTl.iX -
+ aNode.BorderRect().Width();
+ }
+ else
+ {
+ offsetx = previousBorderRect.iTl.iX - marginRight -
+ aNode.BorderRect().Width();
+ }
+ }
+ }
+ else
+ {
+ offsetx = aParentRect.iBr.iX - marginRight -
+ aNode.BorderRect().Width();
+ offsety = aParentRect.iTl.iY + marginTop;
+ }
+ }
+ }
+
+ TRect borderRect = TRect( aNode.BorderRect() );
+ TRect normalFlowBorderRect = TRect( aNode.NormalFlowBorderRect() );
+ // this is the top left corner of margin rect
+ TPoint origin( borderRect.iTl - TPoint( marginLeft, marginTop ) );
+
+ if ( &aParent != &aNode )
+ {
+ // set content rect
+ TRect newRect( aNode.Rect() );
+ newRect.Move( offsetx, offsety );
+ aNode.SetRect( newRect );
+
+ // set padding rect
+ TRect paddingRect( aNode.PaddingRect() );
+ paddingRect.Move( offsetx, offsety );
+ aNode.SetPaddingRect( paddingRect );
+
+ // set border rect
+ borderRect.Move( offsetx, offsety );
+ normalFlowBorderRect.Move( offsetx, offsety );
+ // this is the top left corner of margin rect
+ origin = TPoint( borderRect.iTl - TPoint( marginLeft, marginTop ) );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ }
+
+ TRect marginRect( origin,
+ TSize( marginLeft + marginRight + borderRect.Width(),
+ marginTop + marginBottom + borderRect.Height() ) );
+
+ aNode.SetMarginRect( marginRect );
+
+ // Within this function, the rects are adjusted if the display-priority is
+ // 0 and margin rect exceeds parent's content rect.
+ DropExceedingRectL( aParentRect, aNode );
+
+ // Update column width & column margin width according to block
+ // progression & direction.
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ TInt newColumnWidth = marginRect.iBr.iY - aParentRect.iTl.iY;
+ if ( newColumnWidth > aColumnWidth )
+ {
+ aColumnWidth = newColumnWidth;
+ aColumnMargin = marginRect.iBr.iY - borderRect.iBr.iY;
+ }
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR )
+ {
+ TInt newColumnWidth = aParentRect.iBr.iY - marginRect.iTl.iY;
+ if ( newColumnWidth > aColumnWidth )
+ {
+ aColumnWidth = newColumnWidth;
+ aColumnMargin = borderRect.iTl.iY - marginRect.iTl.iY;
+ }
+ }
+ else if ( aParentDirection ==
+ XnPropertyNames::style::common::direction::KLTR )
+ {
+ // same for tb and bt
+ TInt newColumnWidth = marginRect.iBr.iX - aParentRect.iTl.iX;
+ if ( newColumnWidth > aColumnWidth )
+ {
+ aColumnWidth = newColumnWidth;
+ aColumnMargin = marginRect.iBr.iX - borderRect.iBr.iX;
+ }
+ }
+ else if ( aParentDirection ==
+ XnPropertyNames::style::common::direction::KRTL )
+ {
+ // same for tb and bt
+ TInt newColumnWidth = aParentRect.iBr.iX - marginRect.iTl.iX;
+ if ( newColumnWidth > aColumnWidth )
+ {
+ aColumnWidth = newColumnWidth;
+ aColumnMargin = borderRect.iTl.iX - marginRect.iTl.iX;
+ }
+ }
+
+ if ( IsNodeTooltip( aNode ) )
+ {
+ // because tooltip has it's own window, move margin rect to 0,0
+ // and all other rects as much up left
+ TRect marginRect = aNode.MarginRect();
+ TRect borderRect = aNode.BorderRect();
+ TRect paddingRect = aNode.PaddingRect();
+ TRect contentRect = aNode.Rect();
+ TInt x = marginRect.iTl.iX;
+ TInt y = marginRect.iTl.iY;
+ marginRect.Move( -x, -y );
+ borderRect.Move( -x, -y );
+ paddingRect.Move( -x, -y );
+ contentRect.Move( -x, -y );
+ aNode.SetMarginRect( marginRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetRect( contentRect );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CalculatePaddingL()
+// Move the rect by adding the padding.
+// -----------------------------------------------------------------------------
+//
+static void CalculatePaddingL( const TRect& aParentRect, CXnNode& aNode,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TInt offsetx = 0;
+ TInt offsety = 0;
+
+ TInt paddingleft = 0;
+ TInt paddingright = 0;
+ TInt paddingtop = 0;
+ TInt paddingbottom = 0;
+ TRect parentRect = aParentRect;
+
+ CXnProperty* paddingproperty = aNode.PaddingLeftL();
+
+ if ( paddingproperty )
+ {
+ TRAPD( error, paddingleft = HorizontalPixelValueL( paddingproperty,
+ parentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
+
+ if ( error != KErrNone )
+ {
+ paddingleft = 0;
+ }
+ }
+
+ paddingproperty = aNode.PaddingRightL();
+
+ if ( paddingproperty )
+ {
+ TRAPD( error, paddingright = HorizontalPixelValueL( paddingproperty,
+ parentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
+
+ if ( error != KErrNone )
+ {
+ paddingright = 0;
+ }
+ }
+
+ paddingproperty = aNode.PaddingTopL();
+
+ if ( paddingproperty )
+ {
+ TRAPD( error, paddingtop = VerticalPixelValueL( paddingproperty,
+ parentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
+
+ if ( error != KErrNone )
+ {
+ paddingtop = 0;
+ }
+ }
+
+ paddingproperty = aNode.PaddingBottomL();
+
+ if ( paddingproperty )
+ {
+ TRAPD( error, paddingbottom = VerticalPixelValueL( paddingproperty,
+ parentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
+
+ if ( error != KErrNone )
+ {
+ paddingbottom = 0;
+ }
+ }
+
+ // move the client rect of the element this much right
+ offsetx = paddingleft;
+ // move the client rect of the element this much down
+ offsety = paddingtop;
+
+ TRect newrect( aNode.Rect() );
+ TPoint origin( newrect.iTl );
+ newrect.Move( offsetx, offsety );
+ aNode.SetRect( newrect );
+
+ // set padding rect
+ TRect paddingrect( origin, TSize( paddingleft + paddingright +
+ newrect.Width(), paddingtop + paddingbottom + newrect.Height() ) );
+
+ aNode.SetPaddingRect( paddingrect );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateRectL()
+// Creates rect for CXnComponent.
+// -----------------------------------------------------------------------------
+//
+static void CalculateRectL( CXnNode& aNode, CXnNode& aParent,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TInt width = 0;
+ TInt height = 0;
+ TRect parentRect = aParent.Rect();
+ CXnProperty* widthproperty = aNode.WidthL();
+
+ if ( widthproperty )
+ {
+ // if width is auto, it is set to 0 at this point and calculated later
+ if ( IsPropertyAutoL( *widthproperty ) )
+ {
+ width = 0;
+ }
+ else
+ {
+ width = HorizontalPixelValueL( widthproperty, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+
+ CXnProperty* heightproperty = aNode.HeightL();
+
+ if ( heightproperty )
+ {
+ // if height is auto, height is set to 0 at this point
+ // and calculated later
+ if ( IsPropertyAutoL( *heightproperty ) )
+ {
+ height = 0;
+ }
+ else
+ {
+ height = VerticalPixelValueL( heightproperty, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+
+ // check that rect sizes are in max and min bounds
+ CXnProperty* maxheightproperty = aNode.MaxHeightL();
+ CXnProperty* minheightproperty = aNode.MinHeightL();
+ CXnProperty* maxwidthproperty = aNode.MaxWidthL();
+ CXnProperty* minwidthproperty = aNode.MinWidthL();
+
+ if ( maxwidthproperty )
+ {
+ if ( !IsPropertyNone( *maxwidthproperty ) )
+ {
+ TInt maxwidth = HorizontalPixelValueL(
+ maxwidthproperty, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+
+ if ( width > maxwidth )
+ {
+ width = maxwidth;
+ }
+ }
+ }
+
+ if ( minwidthproperty )
+ {
+ if ( !IsPropertyNone( *minwidthproperty ) )
+ {
+ TInt minwidth = HorizontalPixelValueL(
+ minwidthproperty, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+
+ if ( width < minwidth )
+ {
+ width = minwidth;
+ }
+ }
+ }
+
+ if ( maxheightproperty )
+ {
+ if ( !IsPropertyNone( *maxheightproperty ) )
+ {
+ TInt maxheight = VerticalPixelValueL(
+ maxheightproperty, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+
+ if ( height > maxheight )
+ {
+ height = maxheight;
+ }
+ }
+ }
+
+ if ( minheightproperty )
+ {
+ if ( !IsPropertyNone( *minheightproperty ) )
+ {
+ TInt minheight = VerticalPixelValueL(
+ minheightproperty, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+
+ if ( height < minheight )
+ {
+ height = minheight;
+ }
+ }
+ }
+
+ if ( aNode.ViewNodeImpl() && height != 0 && width != 0 )
+ {
+ TRect rect( 0, 0, width, height );
+ TRect paddingrect( 0, 0, width, height );
+ TRect borderrect( 0, 0, width, height );
+ TRect normalFlowBorderRect( 0, 0, width, height );
+ TRect marginrect( 0, 0, width, height );
+
+ aNode.SetRect( rect );
+ aNode.SetPaddingRect( paddingrect );
+ aNode.SetBorderRect( borderrect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ aNode.SetMarginRect( marginrect );
+ }
+ else if ( !aNode.ViewNodeImpl() )
+ {
+ TInt adaptive( aNode.IsAdaptive() );
+
+ if ( adaptive && ( IsNodeTooltip( aNode ) || IsAbsoluteL( aNode ) ) )
+ {
+ CXnUiEngine* engine( aNode.UiEngine() );
+
+ TSize maxSize( engine->ClientRect().Size() );
+
+ if ( adaptive & XnAdaptive::EHeight )
+ {
+ height = maxSize.iHeight;
+ }
+ if ( adaptive & XnAdaptive::EWidth )
+ {
+ width = maxSize.iWidth;
+ }
+ }
+
+ TRect rect( 0, 0, width, height );
+ TRect paddingrect( 0, 0, width, height );
+ TRect borderrect( 0, 0, width, height );
+ TRect normalFlowBorderRect( 0, 0, width, height );
+ TRect marginrect( 0, 0, width, height );
+
+ aNode.SetRect( rect );
+ aNode.SetPaddingRect( paddingrect );
+ aNode.SetBorderRect( borderrect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ aNode.SetMarginRect( marginrect );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateRelativePositionL()
+// Move the rect by it's relative position.
+// -----------------------------------------------------------------------------
+//
+static void CalculateRelativePositionsL( const TRect& aParentRect,
+ CXnNode& aNode, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
+ {
+ CXnProperty* top = aNode.TopL();
+ CXnProperty* bottom = aNode.BottomL();
+ CXnProperty* left = aNode.LeftL();
+ CXnProperty* right = aNode.RightL();
+
+ // Move rect by offset
+ TRect newRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+
+ TRect parentRect = aParentRect;
+
+ if ( top && !IsPropertyAutoL( *top ) )
+ {
+ newRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ paddingRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ borderRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ marginRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ }
+ if ( bottom && !IsPropertyAutoL( *bottom ) )
+ {
+ newRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ paddingRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ borderRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ marginRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels ) );
+ }
+ if ( left && !IsPropertyAutoL( *left ) )
+ {
+ newRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ paddingRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ borderRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ marginRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ }
+ if ( right && !IsPropertyAutoL( *right ) )
+ {
+ newRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ paddingRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ borderRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ marginRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
+ }
+
+ aNode.SetRect( newRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+
+ DropExceedingRectL( parentRect, aNode, ETrue );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateSpaceUsedByChildrenL()
+// Return space used by node's children.
+// -----------------------------------------------------------------------------
+//
+static TSize CalculateSpaceUsedByChildrenL( RPointerArray< CXnNode >& aChildren,
+ CXnNode& aNode, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, CGraphicsDevice& aScreenDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
+ {
+ TInt usedSiblingHeight( 0 );
+ TInt usedSiblingWidth( 0 );
+
+ TRect rect( aNode.Rect() );
+
+ TSize largestSize( 0, 0 );
+
+ for ( TInt i = 0; i < aChildren.Count(); i++ )
+ {
+ CXnNode* node( aChildren[i] );
+
+ if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
+ !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
+ {
+ TSize siblingSize = CalculateTotalDimensionsL( *node, ETrue,
+ EFalse, rect, aScreenDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+
+ if ( node->IsAdaptive() )
+ {
+ RPointerArray< CXnNode >& children( node->Children() );
+
+ CXnProperty* blockProgressionProperty(
+ node->BlockProgressionL() );
+ CXnProperty* directionProperty( node->DirectionL() );
+
+ const TDesC8* blockProgression(
+ &XnPropertyNames::style::common::block_progression::KTB() );
+ const TDesC8* direction(
+ &XnPropertyNames::style::common::direction::KLTR() );
+
+ if ( directionProperty )
+ {
+ direction = &directionProperty->StringValue();
+ }
+
+ if ( blockProgressionProperty )
+ {
+ blockProgression = &blockProgressionProperty->StringValue();
+ }
+
+ siblingSize += CalculateSpaceUsedByChildrenL( children, aNode,
+ *blockProgression, *direction,
+ aScreenDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+
+ if ( siblingSize.iWidth > largestSize.iWidth )
+ {
+ largestSize.iWidth = siblingSize.iWidth;
+ }
+ if ( siblingSize.iHeight > largestSize.iHeight )
+ {
+ largestSize.iHeight = siblingSize.iHeight;
+ }
+
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB )
+ {
+ usedSiblingHeight += siblingSize.iHeight;
+ usedSiblingWidth = largestSize.iWidth;
+ }
+
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ usedSiblingWidth += siblingSize.iWidth;
+ usedSiblingHeight = largestSize.iHeight;
+ }
+
+ // collapse margins
+ if ( aChildren.Count() < i )
+ {
+ CXnNode* next( aChildren[i + 1] );
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::
+ block_progression::KRL ) && aParentDirection ==
+ XnPropertyNames::style::common::direction::KLTR )
+ {
+ TInt thisSiblingsRightMargin =
+ node->MarginRect().iBr.iX - node->BorderRect().iBr.iX;
+ TInt nextSiblingsLeftMargin =
+ next->BorderRect().iTl.iX - next->MarginRect().iTl.iX;
+
+ if ( nextSiblingsLeftMargin > thisSiblingsRightMargin )
+ {
+ usedSiblingWidth -= thisSiblingsRightMargin;
+ }
+ }
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common
+ ::block_progression::KLR ) && aParentDirection ==
+ XnPropertyNames::style::common::direction::KRTL )
+ {
+ TInt thisSiblingsLeftMargin =
+ node->MarginRect().iTl.iX - node->BorderRect().iTl.iX;
+ TInt nextSiblingsRightMargin =
+ next->BorderRect().iBr.iX - next->MarginRect().iBr.iX;
+
+ if ( nextSiblingsRightMargin > thisSiblingsLeftMargin )
+ {
+ usedSiblingWidth =- thisSiblingsLeftMargin;
+ }
+ }
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::
+ block_progression::KBT ) && aParentDirection ==
+ XnPropertyNames::style::common::direction::KLTR )
+ {
+ TInt thisSiblingsBottomMargin =
+ node->MarginRect().iBr.iY - node->BorderRect().iBr.iY;
+ TInt nextSiblingsTopMargin =
+ next->BorderRect().iTl.iY - next->MarginRect().iTl.iY;
+
+ if ( nextSiblingsTopMargin > thisSiblingsBottomMargin )
+ {
+ usedSiblingHeight -= thisSiblingsBottomMargin;
+ }
+ }
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::
+ block_progression::KBT ) && aParentDirection ==
+ XnPropertyNames::style::common::direction::KRTL )
+ {
+ TInt thisSiblingsTopMargin =
+ node->MarginRect().iTl.iY - node->BorderRect().iTl.iY;
+ TInt nextSiblingsBottomMargin =
+ next->BorderRect().iBr.iY - next->MarginRect().iBr.iY;
+
+ if ( nextSiblingsBottomMargin > thisSiblingsTopMargin )
+ {
+ usedSiblingHeight -= thisSiblingsTopMargin;
+ }
+ }
+ }
+ }
+ }
+
+ return TSize( usedSiblingWidth, usedSiblingHeight );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateTotalDimensionsL()
+// Scale dimensions for areas that have properties set to AUTO.
+// -----------------------------------------------------------------------------
+//
+static TSize CalculateTotalDimensionsL( CXnNode& aNode, TBool aIgnoreAutoValues,
+ TBool aIgnoreMinSizes, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ // AUTO areas return their defined dimensions if not ignored
+ // if ignored, 0 is returned as area dimensions
+ CXnProperty* width( aNode.WidthL() );
+ CXnProperty* height( aNode.HeightL() );
+ TInt adaptive( aNode.IsAdaptive() );
+ TBool autoNotFound( EFalse );
+
+ if ( adaptive )
+ {
+ // Force to measure adaptive size
+ aIgnoreAutoValues = EFalse;
+ autoNotFound = ETrue;
+ }
+ if ( aIgnoreAutoValues )
+ {
+ TInt horizontalAuto( HasNodeHorizontalAutoValuesL( aNode ) );
+ TInt verticalAuto( HasNodeVerticalAutoValuesL( aNode ) );
+ if ( horizontalAuto && verticalAuto )
+ {
+ return TSize( 0, 0 );
+ }
+ else if ( horizontalAuto )
+ {
+ TInt h = VerticalPixelValueL( height, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ return TSize( 0, h );
+ }
+ else if ( verticalAuto )
+ {
+ TInt w = HorizontalPixelValueL( width, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ return TSize( w, 0 );
+ }
+ autoNotFound = ETrue;
+ }
+
+ TInt x( 0 );
+ TInt y( 0 );
+
+ if ( !aIgnoreMinSizes )
+ {
+ if ( !autoNotFound && HasNodeAutoValuesL( aNode ) )
+ {
+ // if auto values, check minimum sizes
+ if ( height )
+ {
+ if ( IsPropertyAutoL( *height ) )
+ {
+ CXnProperty* minheight( aNode.MinHeightL() );
+ if ( minheight )
+ {
+ if ( !IsPropertyNone( *minheight ) )
+ {
+ y += VerticalPixelValueL( minheight,
+ aParentRect.Height(), aGraphicsDevice,
+ aVerticalUnitInPixels );
+ }
+ }
+ }
+ }
+ if ( width )
+ {
+ if ( IsPropertyAutoL( *width ) )
+ {
+ CXnProperty* minwidth( aNode.MinWidthL() );
+ if ( minwidth )
+ {
+ if ( !IsPropertyNone( *minwidth ) )
+ {
+ x += HorizontalPixelValueL( minwidth,
+ aParentRect.Width(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ CXnProperty* marginLeft = aNode.MarginLeftL();
+ CXnProperty* marginRight = aNode.MarginRightL();
+ CXnProperty* borderLeft = aNode.BorderLeftL();
+ CXnProperty* borderRight = aNode.BorderRightL();
+ CXnProperty* paddingLeft = aNode.PaddingLeftL();
+ CXnProperty* paddingRight = aNode.PaddingRightL();
+ CXnProperty* marginTop = aNode.MarginTopL();
+ CXnProperty* marginBottom = aNode.MarginBottomL();
+ CXnProperty* borderTop = aNode.BorderTopL();
+ CXnProperty* borderBottom = aNode.BorderBottomL();
+ CXnProperty* paddingTop = aNode.PaddingTopL();
+ CXnProperty* paddingBottom = aNode.PaddingBottomL();
+ CXnProperty* borderWidth = aNode.BorderWidthL();
+ CXnProperty* borderStyle = aNode.BorderStyleL();
+ CXnProperty* borderImage = aNode.BorderImageL();
+ CXnProperty* borderLeftStyle = aNode.BorderLeftStyleL();
+ CXnProperty* borderRightStyle = aNode.BorderRightStyleL();
+ CXnProperty* borderTopStyle = aNode.BorderTopStyleL();
+ CXnProperty* borderBottomStyle = aNode.BorderBottomStyleL();
+
+ TInt borderWidthValue( 0 );
+ TInt borderHeightValue( 0 );
+ TInt ignore;
+
+ if ( marginLeft )
+ {
+ if ( autoNotFound || !IsPropertyAutoL( *marginLeft ) )
+ {
+ x += HorizontalPixelValueL( marginLeft, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+ if ( marginRight )
+ {
+ if ( autoNotFound || !IsPropertyAutoL( *marginRight ) )
+ {
+ x += HorizontalPixelValueL( marginRight, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+ if ( paddingLeft )
+ {
+ TRAP_IGNORE( x += HorizontalPixelValueL( paddingLeft,
+ aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
+ }
+ if ( paddingRight )
+ {
+ TRAP_IGNORE( x += HorizontalPixelValueL( paddingRight,
+ aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
+ }
+ if ( marginTop )
+ {
+ if ( autoNotFound || !IsPropertyAutoL( *marginTop ) )
+ {
+ y += VerticalPixelValueL( marginTop, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+ if ( marginBottom )
+ {
+ if ( autoNotFound || !IsPropertyAutoL( *marginBottom ) )
+ {
+ y += VerticalPixelValueL( marginBottom, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+ if ( paddingTop )
+ {
+ TRAP_IGNORE( y += VerticalPixelValueL( paddingTop,
+ aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
+ }
+ if ( paddingBottom )
+ {
+ TRAP_IGNORE( y += VerticalPixelValueL( paddingBottom,
+ aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
+ }
+ // is border image or border style defined?
+ // if not, borders are ignored
+ if ( borderWidth )
+ {
+ if ( borderImage || borderStyle )
+ {
+ DetermineBorderWidthsL( borderWidth, borderWidthValue,
+ borderHeightValue, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ x += ( borderWidthValue * 2 );
+ y += ( borderHeightValue * 2 );
+ }
+ }
+ if ( borderLeft )
+ {
+ if ( borderImage || borderStyle || borderLeftStyle )
+ {
+ x -= borderWidthValue;
+ TInt borderLeftValue( 0 );
+ DetermineBorderWidthsL( borderLeft, ignore, borderLeftValue,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ x += borderLeftValue;
+ }
+ }
+ if ( borderRight )
+ {
+ if ( borderImage || borderStyle || borderRightStyle )
+ {
+ x -= borderWidthValue;
+ TInt borderRightValue( 0 );
+ DetermineBorderWidthsL( borderRight, ignore, borderRightValue,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ x += borderRightValue;
+ }
+ }
+ if ( borderTop )
+ {
+ if ( borderImage || borderStyle || borderTopStyle )
+ {
+ y -= borderHeightValue;
+ TInt borderTopValue( 0 );
+ DetermineBorderWidthsL( borderTop, borderTopValue, ignore,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ y += borderTopValue;
+ }
+ }
+ if ( borderBottom )
+ {
+ if ( borderImage || borderStyle || borderBottomStyle )
+ {
+ y -= borderHeightValue;
+ TInt borderBottomValue( 0 );
+ DetermineBorderWidthsL( borderBottom, borderBottomValue, ignore,
+ aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ y += borderBottomValue;
+ }
+ }
+
+ TInt maxHeight( 0 );
+ TInt maxWidth( 0 );
+ TInt minHeight( 0 );
+ TInt minWidth( 0 );
+
+ if ( HasNodeMinSizesL( aNode ) )
+ {
+ CXnProperty* heightproperty( aNode.HeightL() );
+ CXnProperty* widthproperty( aNode.WidthL() );
+ if ( heightproperty )
+ {
+ CXnProperty* minheightproperty( aNode.MinHeightL() );
+ if ( minheightproperty )
+ {
+ if ( !IsPropertyNone( *minheightproperty ) )
+ {
+ minHeight = VerticalPixelValueL( minheightproperty,
+ aParentRect.Height(), aGraphicsDevice,
+ aVerticalUnitInPixels );
+ }
+ }
+ }
+ if ( widthproperty )
+ {
+ CXnProperty* minwidthproperty( aNode.MinWidthL() );
+ if ( minwidthproperty )
+ {
+ if (!IsPropertyNone( *minwidthproperty ) )
+ {
+ minWidth = HorizontalPixelValueL( minwidthproperty,
+ aParentRect.Width(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ }
+ }
+ }
+ }
+ if ( HasNodeMaxSizesL( aNode ) )
+ {
+ CXnProperty* heightProperty( aNode.HeightL() );
+ CXnProperty* widthProperty( aNode.WidthL() );
+ if ( heightProperty )
+ {
+ CXnProperty* maxHeightProperty( aNode.MaxHeightL() );
+ if ( maxHeightProperty )
+ {
+ if ( !IsPropertyNone( *maxHeightProperty ) )
+ {
+ maxHeight = VerticalPixelValueL( maxHeightProperty,
+ aParentRect.Height(), aGraphicsDevice,
+ aVerticalUnitInPixels );
+ }
+ }
+ }
+ if ( widthProperty )
+ {
+ CXnProperty* maxWidthProperty( aNode.MaxWidthL() );
+ if ( maxWidthProperty )
+ {
+ if ( !IsPropertyNone( *maxWidthProperty ) )
+ {
+ maxWidth = HorizontalPixelValueL( maxWidthProperty,
+ aParentRect.Width(), aGraphicsDevice,
+ aHorizontalUnitInPixels );
+ }
+ }
+ }
+ }
+ if ( width && height )
+ {
+ if ( ( adaptive & XnAdaptive::EWidth ) &&
+ ( adaptive & XnAdaptive::EHeight ) )
+ {
+ TSize available( aParentRect.Size() - TSize( x, y ) );
+ if ( available.iWidth > 0 )
+ {
+ if ( available.iWidth > maxWidth && maxWidth > 0 )
+ {
+ available.iWidth = maxWidth;
+ }
+ }
+ if ( available.iHeight > 0 )
+ {
+ if ( available.iHeight > maxHeight && maxHeight > 0 )
+ {
+ available.iHeight = maxHeight;
+ }
+ }
+ TSize size( aNode.MeasureAdaptiveContentL( available ) );
+ x += size.iWidth;
+ y += size.iHeight;
+ if ( minWidth > x )
+ {
+ x = minWidth;
+ }
+ if ( minHeight > y )
+ {
+ y = minHeight;
+ }
+ return TSize( x, y );
+ }
+ }
+ if ( width )
+ {
+ if ( adaptive & XnAdaptive::EWidth )
+ {
+ TSize available( aParentRect.Size() - TSize( x, y ) );
+ if ( available.iWidth > 0 )
+ {
+ if ( available.iWidth > maxWidth && maxWidth > 0 )
+ {
+ available.iWidth = maxWidth;
+ }
+ x += aNode.MeasureAdaptiveContentL( available ).iWidth;
+ if ( minWidth > x )
+ {
+ x = minWidth;
+ }
+ }
+ }
+ else if ( autoNotFound || !IsPropertyAutoL( *width ) )
+ {
+ x += HorizontalPixelValueL( width, aParentRect.Width(),
+ aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+ if ( height )
+ {
+ if ( adaptive & XnAdaptive::EHeight )
+ {
+ TSize available( aParentRect.Size() - TSize( x, y ) );
+ if ( available.iHeight > 0 )
+ {
+ if ( available.iHeight > maxHeight && maxHeight > 0 )
+ {
+ available.iHeight = maxHeight;
+ }
+ y += aNode.MeasureAdaptiveContentL( available ).iHeight;
+ if ( minHeight > y )
+ {
+ y = minHeight;
+ }
+ }
+ }
+ else if ( autoNotFound || !IsPropertyAutoL( *height ) )
+ {
+ y += VerticalPixelValueL( height, aParentRect.Height(),
+ aGraphicsDevice, aVerticalUnitInPixels );
+ }
+ }
+ return TSize( x, y );
+ }
+
+// -----------------------------------------------------------------------------
+// CutOnePixelFromPercentChildNodeL()
+// If node has a child node with percentace defined sizes,
+// one pixel may be cut off from it to fix possible rounding problem.
+// -----------------------------------------------------------------------------
+//
+static TBool CutOnePixelFromPercentChildNodeL( CXnNode& aNode,
+ const TDesC8& aParentBlockProgression )
+ {
+ RPointerArray< CXnNode >& children = aNode.Children();
+ // find the last percent value node
+ // possible percent values:
+ // width
+ // height
+ // paddings
+ // margins
+ // borders
+ for ( TInt i = children.Count() -1; i < -1 ; --i )
+ {
+ CXnNode* currentNode = children[i];
+
+ TInt x = 0;
+ TInt y = 0;
+
+ CXnProperty* widthHeight;
+ CXnProperty* paddingTopLeft;
+ CXnProperty* paddingBottomRight;
+ CXnProperty* borderTopLeft;
+ CXnProperty* borderBottomRight;
+ CXnProperty* marginTopLeft;
+ CXnProperty* marginBottomRight;
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ) ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ x = -1;
+ y = 0;
+ widthHeight = currentNode->WidthL();
+ paddingTopLeft = currentNode->PaddingLeftL();
+ paddingBottomRight = currentNode->PaddingRightL();
+ borderTopLeft = currentNode->BorderLeftL();
+ borderBottomRight = currentNode->BorderRightL();
+ marginTopLeft = currentNode->MarginLeftL();
+ marginBottomRight = currentNode->MarginRightL();
+ }
+ else
+ {
+ y = -1;
+ x = 0;
+ widthHeight = currentNode->HeightL();
+ paddingTopLeft = currentNode->PaddingTopL();
+ paddingBottomRight = currentNode->PaddingBottomL();
+ borderTopLeft = currentNode->BorderTopL();
+ borderBottomRight = currentNode->BorderBottomL();
+ marginTopLeft = currentNode->MarginTopL();
+ marginBottomRight = currentNode->MarginBottomL();
+ }
+ if ( widthHeight )
+ {
+ if ( IsValuePercentageL( *widthHeight ) )
+ {
+ // shrink width one pixel
+ TRect rect( currentNode->Rect() );
+ rect.Resize( x, y );
+ currentNode->SetRect( rect );
+ TRect paddingRect( currentNode->PaddingRect() );
+ paddingRect.Resize( x, y );
+ currentNode->SetPaddingRect( paddingRect );
+ TRect borderRect( currentNode->BorderRect() );
+ borderRect.Resize( x, y );
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ if ( paddingTopLeft )
+ {
+ if ( IsValuePercentageL( *paddingTopLeft ) )
+ {
+ // shrink left padding one pixel
+ TRect rect( currentNode->Rect() );
+ rect.Move( x, y );
+ currentNode->SetRect( rect );
+ TRect paddingRect( currentNode->PaddingRect() );
+ paddingRect.Resize( x, y );
+ currentNode->SetPaddingRect( paddingRect );
+ TRect borderRect( currentNode->BorderRect() );
+ TRect normalFlowBorderRect(
+ currentNode->NormalFlowBorderRect() );
+ borderRect.Resize( x, y );
+ normalFlowBorderRect.Resize( x, y );
+ currentNode->SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ if ( paddingBottomRight )
+ {
+ if ( IsValuePercentageL( *paddingBottomRight ) )
+ {
+ // shrink right padding one pixel
+ TRect paddingRect( currentNode->PaddingRect() );
+ paddingRect.Resize( x, y );
+ currentNode->SetPaddingRect( paddingRect );
+ TRect borderRect( currentNode->BorderRect() );
+ TRect normalFlowBorderRect(
+ currentNode->NormalFlowBorderRect() );
+ borderRect.Resize( x, y );
+ normalFlowBorderRect.Resize( x, y );
+ currentNode->SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ if ( borderTopLeft )
+ {
+ if ( IsValuePercentageL( *borderTopLeft ) )
+ {
+ TRect rect( currentNode->Rect() );
+ rect.Move( x, y );
+ currentNode->SetRect( rect );
+ TRect paddingRect( currentNode->PaddingRect() );
+ paddingRect.Move( x, y );
+ currentNode->SetPaddingRect( paddingRect );
+ TRect borderRect( currentNode->BorderRect() );
+ TRect normalFlowBorderRect(
+ currentNode->NormalFlowBorderRect() );
+ borderRect.Resize( x, y );
+ normalFlowBorderRect.Resize( x, y );
+ currentNode->SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ if ( borderBottomRight )
+ {
+ if ( IsValuePercentageL( *borderBottomRight ) )
+ {
+ TRect borderRect( currentNode->BorderRect() );
+ TRect normalFlowBorderRect( currentNode->BorderRect() );
+ borderRect.Resize( x, y );
+ normalFlowBorderRect.Resize( x, y );
+ currentNode->SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ if ( marginTopLeft )
+ {
+ if ( IsValuePercentageL( *marginTopLeft ) )
+ {
+ TRect rect( currentNode->Rect() );
+ rect.Move( x, y );
+ currentNode->SetRect( rect );
+ TRect paddingRect( currentNode->PaddingRect() );
+ paddingRect.Move( x, y );
+ currentNode->SetPaddingRect( paddingRect );
+ TRect borderRect( currentNode->BorderRect() );
+ TRect normalFlowBorderRect(
+ currentNode->NormalFlowBorderRect() );
+ borderRect.Move( x, y );
+ normalFlowBorderRect.Move( x, y );
+ currentNode->SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ if ( marginBottomRight )
+ {
+ if ( IsValuePercentageL( *marginBottomRight ) )
+ {
+ TRect marginRect( currentNode->MarginRect() );
+
+ marginRect.Resize( x, y );
+
+ currentNode->SetMarginRect( marginRect );
+
+ return ETrue;
+ }
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// DetermineBorderWidthsL()
+// Determine border widths.
+// -----------------------------------------------------------------------------
+//
+static void DetermineBorderWidthsL( CXnProperty* aBorderWidthProperty,
+ TInt& aBordervertical, TInt& aBorderhorizontal, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ CXnDomList& propertyValueList =
+ aBorderWidthProperty->Property()->PropertyValueList();
+ for ( TInt i = propertyValueList.Length() - 1; i >= 0; --i )
+ {
+ CXnDomPropertyValue* value =
+ static_cast< CXnDomPropertyValue* >( propertyValueList.Item( i ) );
+ if ( value->PrimitiveValueType() == CXnDomPropertyValue::EString ||
+ value->PrimitiveValueType() == CXnDomPropertyValue::EIdent )
+ {
+ // border width was defined as string
+ const TDesC8& borderwidth = aBorderWidthProperty->StringValue();
+ if ( borderwidth ==
+ XnPropertyNames::style::common::border_width::KThin )
+ {
+ aBordervertical = KXnBorderThin;
+ aBorderhorizontal = KXnBorderThin;
+ }
+ else if ( borderwidth ==
+ XnPropertyNames::style::common::border_width::KMedium )
+ {
+ aBordervertical = KXnBorderMedium;
+ aBorderhorizontal = KXnBorderMedium;
+ }
+ else
+ {
+ aBordervertical = KXnBorderThick;
+ aBorderhorizontal = KXnBorderThick;
+ }
+ }
+ else
+ {
+ // border width was defined as int
+ aBordervertical = VerticalPixelValueL( aBorderWidthProperty,
+ aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
+ aBorderhorizontal = HorizontalPixelValueL( aBorderWidthProperty,
+ aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DisplayedChildrenCountL()
+// Return number of node's displayed children.
+// -----------------------------------------------------------------------------
+//
+static TInt DisplayedChildrenCountL( CXnNode& aNode,
+ RPointerArray< CXnNode >* aDisplayedChildren )
+ {
+ RPointerArray< CXnNode >& children = aNode.Children();
+ TInt displayedCount( 0 );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNode* node( children[i] );
+ if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
+ !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
+ {
+ if ( aDisplayedChildren )
+ {
+ aDisplayedChildren->AppendL( node );
+ }
+ displayedCount++;
+ }
+ }
+
+ return displayedCount;
+ }
+
+// -----------------------------------------------------------------------------
+// DisplayedParentL()
+// Return node's displayed parent.
+// -----------------------------------------------------------------------------
+//
+static CXnNode* DisplayedParentL( CXnNode& aNode )
+ {
+ if ( aNode.ViewNodeImpl() )
+ {
+ return &aNode;
+ }
+ CXnNode* parent = aNode.Parent();
+ return parent;
+ }
+
+// -----------------------------------------------------------------------------
+// DomPropertyValueFromProperty()
+// Return DOM property value from property.
+// -----------------------------------------------------------------------------
+//
+static CXnDomPropertyValue* DomPropertyValueFromProperty(
+ CXnProperty* aProperty )
+ {
+ if ( !aProperty )
+ {
+ return NULL;
+ }
+ CXnDomProperty* domProperty = aProperty->Property();
+ if ( !domProperty )
+ {
+ return NULL;
+ }
+ return static_cast<
+ CXnDomPropertyValue* >( domProperty->PropertyValueList().Item( 0 ) );
+ }
+
+// -----------------------------------------------------------------------------
+// DomPropertyValueFromProperty()
+// Return DOM property value from property.
+// -----------------------------------------------------------------------------
+//
+static TBool IsChildOfScrollableControl( CXnNode& aNode )
+ {
+ CXnNode* parent = &aNode;
+ while( parent )
+ {
+ if( IsSrollableBox( *parent ) )
+ {
+ return ETrue;
+ }
+ parent = parent->Parent();
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// DropExceedingRectL()
+// Drop node if node's margin rect exceeds it's parent's content rect.
+// -----------------------------------------------------------------------------
+//
+static void DropExceedingRectL( const TRect& aParentRect, CXnNode& aNode,
+ TBool aDropRelativeNode )
+ {
+ if( IsChildOfScrollableControl( aNode ) )
+ {
+ return;
+ }
+
+ if ( IsNodeTooltip( aNode ) )
+ {
+ // tooltip never dropped
+ return;
+ }
+
+ CXnProperty* positionProp( aNode.PositionL() );
+
+ if ( positionProp )
+ {
+ const TDesC8& value( positionProp->StringValue() );
+ if ( value == XnPropertyNames::style::common::position::KFloating )
+ {
+ // Don't change floating positioned box dimensions
+ return;
+ }
+ }
+
+ TRect parentRect( aParentRect );
+ TRect marginRect( aNode.MarginRect() );
+
+ // does the margin rect fit in its parent?
+ TInt parentLeft = parentRect.iTl.iX;
+ TInt parentRight = parentRect.iBr.iX;
+ TInt parentTop = parentRect.iTl.iY;
+ TInt parentBottom = parentRect.iBr.iY;
+
+ TInt rectLeft = marginRect.iTl.iX;
+ TInt rectRight = marginRect.iBr.iX;
+ TInt rectTop = marginRect.iTl.iY;
+ TInt rectBottom = marginRect.iBr.iY;
+
+ TInt priority = 0;
+ CXnProperty* priorityProperty = aNode.DisplayPriorityL();
+
+ if ( priorityProperty )
+ {
+ TRAPD( error, priority = priorityProperty->FloatValueL() );
+ if ( error != KErrNone )
+ {
+ priority = 0;
+ }
+ }
+
+ TInt leftOffset( 0 );
+ TInt rightOffset( 0 );
+ TInt topOffset( 0 );
+ TInt bottomOffset( 0 );
+
+ if ( priority != 0 )
+ {
+ TBool drop = CalculateExceedingArea( *aNode.Parent(), aNode,
+ leftOffset, rightOffset, topOffset, bottomOffset );
+ if ( drop )
+ {
+ aNode.UiEngine()->SetNodeDroppedL( aNode, XnNodeLayout::EDropped );
+ }
+ }
+ // If display priority is 0 as much as possible must be shown, but
+ // parent's content rect must not be exceeded.
+ else
+ {
+ // This must not be done for tracster. It is a special component,
+ // which takes care
+ // of its final layout and therefore its children can exceed
+ // the parent's rect.
+ CXnNode* parent = aNode.Parent();
+
+ // If the node is relatively positioned, and this is not called from
+ // CalculateRelativePositionsL(), then must not be cropped!!
+
+ // Default is static
+ const TDesC8* value(
+ &XnPropertyNames::style::common::position::KStatic() );
+
+ if ( positionProp && positionProp->StringValue() != KNullDesC8 )
+ {
+ value = &positionProp->StringValue();
+ }
+ if ( !aDropRelativeNode &&
+ XnPropertyNames::style::common::position::KRelative() == *value )
+ // relative nodes must not be adjusted, if this is not called
+ // from CalculateRelativePositionsL().
+ {
+ return;
+ }
+ if ( rectLeft < parentLeft )
+ {
+ leftOffset = parentLeft - rectLeft;
+ }
+ if ( rectRight > parentRight )
+ {
+ rightOffset = rectRight - parentRight;
+ }
+ if ( rectTop < parentTop )
+ {
+ topOffset = parentTop - rectTop;
+ }
+ if ( rectBottom > parentBottom )
+ {
+ bottomOffset = rectBottom - parentBottom;
+ }
+ AdjustRectsL( aNode, leftOffset, rightOffset, topOffset, bottomOffset );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateExceedingArea()
+// Calculates how much a dropped node affects to the area of its parent
+// that is content based node.
+// Returns whether a child's margin rect exceeds its parents content
+// rect or not.
+// -----------------------------------------------------------------------------
+//
+static TBool CalculateExceedingArea( CXnNode& aParent, CXnNode& aChild,
+ TInt& aLeftOffset, TInt& aRightOffset, TInt& aTopOffset,
+ TInt& aBottomOffset )
+ {
+ TBool ret( EFalse );
+
+ TRect parentRect( aParent.Rect() );
+ TInt parentLeft = parentRect.iTl.iX;
+ TInt parentRight = parentRect.iBr.iX;
+ TInt parentTop = parentRect.iTl.iY;
+ TInt parentBottom = parentRect.iBr.iY;
+
+ TRect marginRect( aChild.MarginRect() );
+ TInt rectLeft = marginRect.iTl.iX;
+ TInt rectRight = marginRect.iBr.iX;
+ TInt rectTop = marginRect.iTl.iY;
+ TInt rectBottom = marginRect.iBr.iY;
+
+ TInt adaptive( aParent.IsAdaptive() );
+
+ if ( rectLeft < parentLeft )
+ {
+ if ( adaptive & XnAdaptive::EWidth )
+ {
+ aLeftOffset = rectRight - parentLeft;
+ if ( aLeftOffset < 0 )
+ {
+ aLeftOffset = 0;
+ }
+ }
+ ret = ETrue;
+ }
+ if ( rectRight > parentRight )
+ {
+ if ( adaptive & XnAdaptive::EWidth )
+ {
+ aRightOffset = parentRight - rectLeft;
+ if ( aRightOffset < 0 )
+ {
+ aRightOffset = 0;
+ }
+ }
+ ret = ETrue;
+ }
+ if ( rectTop < parentTop )
+ {
+ if ( adaptive & XnAdaptive::EHeight )
+ {
+ aTopOffset = rectBottom - parentTop;
+ if ( aTopOffset < 0 )
+ {
+ aTopOffset = 0;
+ }
+ }
+ ret = ETrue;
+ }
+ if ( rectBottom > parentBottom )
+ {
+ if ( adaptive & XnAdaptive::EHeight )
+ {
+ aBottomOffset = parentBottom - rectTop;
+ if ( aBottomOffset < 0 )
+ {
+ aBottomOffset = 0;
+ }
+ }
+ ret = ETrue;
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// AdjustRectsL()
+// Adjust all the rects according to the given offsets.
+// -----------------------------------------------------------------------------
+//
+static void AdjustRectsL( CXnNode& aNode, TInt aLeftOffset, TInt aRightOffset,
+ TInt aTopOffset, TInt aBottomOffset )
+ {
+ if ( aLeftOffset || aRightOffset || aTopOffset || aBottomOffset )
+ {
+#ifdef _XN3_DEBUG_
+ CXnProperty* id( aNode.IdL() );
+
+ if ( id )
+ {
+ TBuf8< 256 > debug;
+ debug.Append( _L8( "Node id: " ) );
+ debug.Append( id->StringValue() );
+ debug.Append( _L8( "doesn't fit to parent and will be adjusted" ) );
+
+ RDebug::RawPrint( debug );
+ }
+#endif
+
+ // Adjust margin rect
+ TRect marginRect( aNode.MarginRect() );
+ TRect newRect = TRect( marginRect.iTl.iX + aLeftOffset,
+ marginRect.iTl.iY + aTopOffset, marginRect.iBr.iX - aRightOffset,
+ marginRect.iBr.iY - aBottomOffset );
+ aNode.SetMarginRect( newRect );
+
+ // Adjust border rect
+ TRect borderRect( aNode.BorderRect() );
+ newRect = TRect( borderRect.iTl.iX + aLeftOffset,
+ borderRect.iTl.iY + aTopOffset, borderRect.iBr.iX - aRightOffset,
+ borderRect.iBr.iY - aBottomOffset );
+ aNode.SetBorderRect( newRect );
+
+ // Adjust normal flow border rect
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+ newRect = TRect( normalFlowBorderRect.iTl.iX + aLeftOffset,
+ normalFlowBorderRect.iTl.iY + aTopOffset,
+ normalFlowBorderRect.iBr.iX - aRightOffset,
+ normalFlowBorderRect.iBr.iY - aBottomOffset );
+ aNode.SetNormalFlowBorderRect( newRect );
+
+ // Adjust padding rect
+ TRect paddingRect( aNode.PaddingRect() );
+ newRect = TRect( paddingRect.iTl.iX + aLeftOffset,
+ paddingRect.iTl.iY + aTopOffset, paddingRect.iBr.iX - aRightOffset,
+ paddingRect.iBr.iY - aBottomOffset );
+ aNode.SetPaddingRect( newRect );
+
+ // Adjust content rect
+ TRect contentRect( aNode.Rect() );
+ newRect = TRect( contentRect.iTl.iX + aLeftOffset,
+ contentRect.iTl.iY + aTopOffset, contentRect.iBr.iX - aRightOffset,
+ contentRect.iBr.iY - aBottomOffset );
+ aNode.SetRect( newRect );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ClearRects()
+// Sets sizes of the rects to 0.
+// -----------------------------------------------------------------------------
+//
+static void ClearRects( CXnNode& aNode, TBool aRecurse )
+ {
+ TRect empty;
+
+ aNode.SetRect( empty );
+ aNode.SetPaddingRect( empty );
+ aNode.SetBorderRect( empty );
+ aNode.SetNormalFlowBorderRect( empty );
+ aNode.SetMarginRect( empty );
+
+ CCoeControl* control( aNode.Control() );
+
+ if ( control )
+ {
+ control->SetRect( empty );
+ }
+
+ if ( aRecurse )
+ {
+ RPointerArray< CXnNode >& children( aNode.Children() );
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ ClearRects( *children[i], aRecurse );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// FitChildrenIntoParentL()
+// Drop child nodes until they fit into the parent. Also, if node has
+// a child node with percentace defined sizes, one pixel may be cut off from it
+// to fix possible rounding problem.
+// -----------------------------------------------------------------------------
+//
+static void FitChildrenIntoParentL( CXnNode& aNode,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ if( IsSrollableBox( aNode ) )
+ {
+ return;
+ }
+ RPointerArray< CXnNode >& children( aNode.Children() );
+
+ if ( children.Count() == 0 )
+ {
+ return;
+ }
+
+ CXnProperty* blockProgressionProperty( aNode.BlockProgressionL() );
+ CXnProperty* directionProperty( aNode.DirectionL() );
+
+ const TDesC8* blockProgression = NULL;
+
+ if ( !blockProgressionProperty )
+ {
+ // using default
+ blockProgression =
+ &XnPropertyNames::style::common::block_progression::KTB();
+ }
+ else
+ {
+ blockProgression = &blockProgressionProperty->StringValue();
+ }
+
+ const TDesC8* direction( NULL );
+
+ if ( !directionProperty )
+ {
+ // use default
+ direction = &XnPropertyNames::style::common::direction::KLTR();
+ }
+ else
+ {
+ direction = &directionProperty->StringValue();
+ }
+
+ TSize space = CalculateSpaceUsedByChildrenL( children, aNode,
+ *blockProgression, *direction, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ TSize parentSize( aNode.Rect().Size() );
+
+ while( ( ( parentSize.iHeight < space.iHeight ) &&
+ ( parentSize.iHeight > 0 ) ) ||
+ ( ( parentSize.iWidth < space.iWidth ) &&
+ ( parentSize.iWidth > 0 ) ) )
+ {
+ // if areas go over just one pixel,
+ // cut the pixel from a percent sized node
+ if ( ( parentSize.iHeight == space.iHeight - 1 ) ||
+ ( parentSize.iWidth == space.iWidth - 1 ) )
+ {
+ CutOnePixelFromPercentChildNodeL( aNode, *blockProgression );
+ // Childs are now in parent size
+ return;
+ }
+
+ TInt childCount( DisplayedChildrenCountL( aNode ) );
+
+ PriorizeChildrenL( aNode );
+
+ if ( DisplayedChildrenCountL( aNode ) == childCount )
+ {
+ // cannot drop any more children, but they still don't fit
+ return;
+ }
+
+ space = CalculateSpaceUsedByChildrenL( children, aNode,
+ *blockProgression, *direction, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ }
+
+ return;
+ }
+
+// -----------------------------------------------------------------------------
+// GetPositionL()
+// Return position coordinate of a CXnComponent. Returned position depends on
+// given block progression.
+// -----------------------------------------------------------------------------
+//
+static TInt GetPositionL( CXnNode& aNode, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection )
+ {
+ TInt returnValue = 0;
+ if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ returnValue = aNode.NormalFlowBorderRect().iBr.iY;
+ }
+ else // LR or RL
+ {
+ returnValue = aNode.NormalFlowBorderRect().iBr.iX;
+ }
+ }
+ else // RTL
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ returnValue = aNode.NormalFlowBorderRect().iTl.iY;
+ }
+ else // LR or RL
+ {
+ returnValue = aNode.NormalFlowBorderRect().iTl.iX;
+ }
+ }
+ return returnValue;
+ }
+
+// -----------------------------------------------------------------------------
+// HasNodeAutoValues()
+// Check if node has properties set to AUTO.
+// -----------------------------------------------------------------------------
+//
+static TInt HasNodeAutoValuesL( CXnNode& aNode )
+ {
+ return HasNodeHorizontalAutoValuesL( aNode ) ||
+ HasNodeVerticalAutoValuesL( aNode );
+ }
+
+// -----------------------------------------------------------------------------
+// HasNodeHorizontalValues()
+// Check if node has properties set to AUTO.
+// -----------------------------------------------------------------------------
+//
+static TInt HasNodeHorizontalAutoValuesL( CXnNode& aNode )
+ {
+ TInt autoCount = 0;
+
+ CXnProperty* width = aNode.WidthL();
+
+ if ( width )
+ {
+ if ( IsPropertyAutoL( *width ) )
+ {
+ autoCount++;
+ }
+ }
+ else
+ {
+ // width is auto as default
+ autoCount++;
+ }
+
+ CXnProperty* marginleft = aNode.MarginLeftL();
+
+ if ( marginleft )
+ {
+ if ( IsPropertyAutoL( *marginleft ) )
+ {
+ autoCount++;
+ }
+ }
+
+ CXnProperty* marginright = aNode.MarginRightL();
+
+ if ( marginright )
+ {
+ if ( IsPropertyAutoL( *marginright ) )
+ {
+ autoCount++;
+ }
+ }
+
+ if ( !IsAbsoluteL( aNode ) && !IsRelativeL( aNode ) )
+ {
+ return autoCount;
+ }
+
+ CXnProperty* left = aNode.LeftL();
+
+ if ( left )
+ {
+ if ( IsPropertyAutoL( *left ) )
+ {
+ autoCount++;
+ }
+ }
+
+ CXnProperty* right = aNode.RightL();
+
+ if ( right )
+ {
+ if ( IsPropertyAutoL( *right ) )
+ {
+ autoCount++;
+ }
+ }
+
+ return autoCount;
+ }
+
+// -----------------------------------------------------------------------------
+// HasNodeVerticalAutoValues()
+// Check if node has properties set to AUTO.
+// -----------------------------------------------------------------------------
+//
+static TInt HasNodeVerticalAutoValuesL( CXnNode& aNode )
+ {
+ TInt autoCount = 0;
+
+ CXnProperty* height = aNode.HeightL();
+
+ if ( height )
+ {
+ if ( IsPropertyAutoL( *height ) )
+ {
+ autoCount++;
+ }
+ }
+ else
+ {
+ // height is auto as default
+ autoCount++;
+ }
+
+ CXnProperty* margintop = aNode.MarginTopL();
+
+ if ( margintop )
+ {
+ if ( IsPropertyAutoL( *margintop ) )
+ {
+ autoCount++;
+ }
+ }
+
+ CXnProperty* marginbottom = aNode.MarginBottomL();
+
+ if ( marginbottom )
+ {
+ if ( IsPropertyAutoL( *marginbottom ) )
+ {
+ autoCount++;
+ }
+ }
+
+ if ( !IsAbsoluteL( aNode ) && !IsRelativeL( aNode ) )
+ {
+ return autoCount;
+ }
+
+ CXnProperty* top = aNode.TopL();
+
+ if ( top )
+ {
+ if ( IsPropertyAutoL( *top ) )
+ {
+ autoCount++;
+ }
+ }
+
+ CXnProperty* bottom = aNode.BottomL();
+
+ if ( bottom )
+ {
+ if ( IsPropertyAutoL( *bottom ) )
+ {
+ autoCount++;
+ }
+ }
+
+ return autoCount;
+ }
+
+// -----------------------------------------------------------------------------
+// HasNodeMinSizesL()
+// Check if node has minimum size values.
+// -----------------------------------------------------------------------------
+//
+static TBool HasNodeMinSizesL( CXnNode& aNode )
+ {
+ CXnProperty* minWidth = aNode.MinWidthL();
+
+ if ( minWidth )
+ {
+ if ( !IsPropertyNone( *minWidth ) )
+ {
+ return ETrue;
+ }
+ }
+
+ CXnProperty* minHeight = aNode.MinHeightL();
+
+ if ( minHeight )
+ {
+ if ( !IsPropertyNone( *minHeight ) )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// HasNodeMaxSizesL()
+// Check if node has maximum size values.
+// -----------------------------------------------------------------------------
+//
+static TBool HasNodeMaxSizesL( CXnNode& aNode )
+ {
+ CXnProperty* maxWidth = aNode.MaxWidthL();
+
+ if ( maxWidth )
+ {
+ if ( !IsPropertyNone( *maxWidth ) )
+ {
+ return ETrue;
+ }
+ }
+
+ CXnProperty* maxHeight = aNode.MaxHeightL();
+
+ if ( maxHeight )
+ {
+ if ( !IsPropertyNone( *maxHeight ) )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalCentimetersToPixelsL()
+// Convert horizontal centimeter value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalCentimetersToPixelsL( TReal& aCentimeters,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aCentimeters * KCentimetersAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.HorizontalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalInchesToPixelsL()
+// Convert horizontal inch value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalInchesToPixelsL( TReal& aInches,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aInches * KInchesAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.HorizontalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalMillimetersToPixelsL()
+// Convert horizontal millimeter value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalMillimetersToPixelsL( TReal& aMillimeters,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aMillimeters * KMillimetersAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.HorizontalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalPicasToPixelsL()
+// Convert horizontal pica value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalPicasToPixelsL( TReal& aPicas,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aPicas * KPicasAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.HorizontalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalPixelValueL()
+// Convert horizontal property to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels )
+ {
+ return HorizontalValueToPixelsL( DomPropertyValueFromProperty( aValue ),
+ static_cast< TReal >( aReferenceValue ), aScreenDevice,
+ aHorizontalUnitInPixels );
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalPointsToPixelsL()
+// Convert horizontal point value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalPointsToPixelsL( TReal& aPoints,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aPoints * KPointsAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.HorizontalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalUnitsToPixelsL()
+// Convert horizontal unit value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalUnitsToPixelsL( TReal aUnits, TReal aUnitInPixels )
+ {
+ TInt pixels = aUnits * aUnitInPixels;
+ return pixels;
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalUnitsToPixelsL()
+// Convert vertical unit value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalUnitsToPixelsL( TReal aUnits, TReal aUnitInPixels )
+ {
+ TInt pixels = aUnits * aUnitInPixels;
+ return pixels;
+ }
+
+// -----------------------------------------------------------------------------
+// HorizontalValueToPixelsL()
+// Convert horizontal property value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt HorizontalValueToPixelsL( CXnDomPropertyValue* aValue,
+ TReal aReferenceValue, CGraphicsDevice& aScreenDevice, TReal aUnitInPixels )
+ {
+ if ( !aValue )
+ {
+ User::Leave( KXnErrHorizontalValueNULL );
+ }
+ CXnDomPropertyValue::TPrimitiveValueType valueType =
+ aValue->PrimitiveValueType();
+ // Handle error cases first, inherit is handled elsewhere, none returns 0
+ switch ( valueType )
+ {
+ case CXnDomPropertyValue::EUnknown:
+ case CXnDomPropertyValue::EEms:
+ case CXnDomPropertyValue::EExs:
+ case CXnDomPropertyValue::EDeg:
+ case CXnDomPropertyValue::ERad:
+ case CXnDomPropertyValue::EGrad:
+ case CXnDomPropertyValue::EMs:
+ case CXnDomPropertyValue::ES:
+ case CXnDomPropertyValue::EHz:
+ case CXnDomPropertyValue::EKHz:
+ case CXnDomPropertyValue::EDimension:
+ case CXnDomPropertyValue::EString:
+ case CXnDomPropertyValue::EUri:
+ case CXnDomPropertyValue::EIdent:
+ case CXnDomPropertyValue::EAttr:
+ case CXnDomPropertyValue::ECounter:
+ case CXnDomPropertyValue::ERect:
+ case CXnDomPropertyValue::ERgbColor:
+ case CXnDomPropertyValue::ERgbaColor:
+ case CXnDomPropertyValue::EFunction:
+ break;
+ default:
+ {
+ TReal value = aValue->FloatValueL();
+ if ( valueType == CXnDomPropertyValue::ENumber ||
+ valueType == CXnDomPropertyValue::EPx )
+ {
+ return static_cast< TInt >( value );
+ }
+ else if ( valueType == CXnDomPropertyValue::EPercentage )
+ {
+ return PercentageToPixelsL( value, aReferenceValue );
+ }
+ else if ( valueType == CXnDomPropertyValue::EIn )
+ {
+ return HorizontalInchesToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::ECm )
+ {
+ return HorizontalCentimetersToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EMm )
+ {
+ return HorizontalMillimetersToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EPt )
+ {
+ return HorizontalPointsToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EPc )
+ {
+ return HorizontalPicasToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EUnitValue )
+ {
+ return HorizontalUnitsToPixelsL( value, aUnitInPixels );
+ }
+ }
+ break;
+ }
+
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// IsAbsoluteL()
+// Check if node's positioning is absolute.
+// -----------------------------------------------------------------------------
+//
+static TBool IsAbsoluteL( CXnNode& aNode )
+ {
+ CXnProperty* prop( aNode.PositionL() );
+
+ if ( prop )
+ {
+ const TDesC8& value( prop->StringValue() );
+ if ( value == XnPropertyNames::style::common::position::KAbsolute ||
+ value == XnPropertyNames::style::common::position::KFloating )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsLargerThanMaxSizeL()
+// Check if node rect size exceeds it's max sizes.
+// -----------------------------------------------------------------------------
+//
+static TBool IsLargerThanMaxSizeL( const TRect& aParentRect, CXnNode& aNode,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TRect parentRect = aParentRect;
+ CXnProperty* heightProperty = aNode.HeightL();
+ CXnProperty* widthProperty = aNode.WidthL();
+
+ if ( heightProperty )
+ {
+ CXnProperty* maxHeightProperty = aNode.MaxHeightL();
+ if ( maxHeightProperty )
+ {
+ if ( !IsPropertyNone( *maxHeightProperty ) )
+ {
+ TInt maxHeight = VerticalPixelValueL( maxHeightProperty,
+ parentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
+ TInt height = aNode.Rect().Height();
+ if ( height > maxHeight )
+ {
+ // height larger than max
+ return ETrue;
+ }
+ }
+ }
+ }
+
+ if ( widthProperty )
+ {
+ CXnProperty* maxWidthProperty = aNode.MaxWidthL();
+ if ( maxWidthProperty )
+ {
+ if ( !IsPropertyNone( *maxWidthProperty ) )
+ {
+ TInt maxWidth = HorizontalPixelValueL( maxWidthProperty,
+ parentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
+ TInt width = aNode.Rect().Width();
+ if ( width > maxWidth )
+ {
+ // width larger than max
+ return ETrue;
+ }
+ }
+ }
+ }
+
+ // width and height within limits
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsNodeDisplayedL()
+// Check if node is able to be displayed.
+// -----------------------------------------------------------------------------
+//
+static TBool IsNodeDisplayedL( CXnNode& aNode )
+ {
+ if ( !aNode.IsLayoutCapable() )
+ {
+ return EFalse;
+ }
+
+ // Am I displayed?
+ CXnProperty* displayProp( aNode.DisplayL() );
+
+ if ( displayProp )
+ {
+ const TDesC8& display( displayProp->StringValue() );
+
+ if ( display != XnPropertyNames::style::common::display::KBlock )
+ {
+ return EFalse;
+ }
+ }
+
+ CXnNode* parent( aNode.Parent() );
+
+ // Is my parent displayed?
+ for ( ; parent; parent = parent->Parent() )
+ {
+ CXnProperty* displayProp( parent->DisplayL() );
+
+ if ( displayProp )
+ {
+ const TDesC8& display( displayProp->StringValue() );
+
+ if ( display != XnPropertyNames::style::common::display::KBlock )
+ {
+ return EFalse;
+ }
+ }
+ }
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// IsNodeTooltip()
+// Check if node is a tooltip.
+// -----------------------------------------------------------------------------
+//
+static TBool IsNodeTooltip( CXnNode& aNode )
+ {
+ _LIT8( tooltip, "tooltip" );
+
+ if ( aNode.Type()->Type() == tooltip )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsPropertyAutoL()
+// Check if property is set to AUTO.
+// -----------------------------------------------------------------------------
+//
+static TBool IsPropertyAutoL( CXnProperty& aProperty )
+ {
+ if ( &aProperty )
+ {
+ TBool returnValue;
+ TInt index = 0;
+ CXnDomProperty* domProperty = aProperty.Property();
+ CXnDomPropertyValue* domPropertyValue =
+ static_cast< CXnDomPropertyValue* >(
+ domProperty->PropertyValueList().Item( index ) );
+ returnValue = domPropertyValue->IsAutoIdent();
+ if ( !returnValue )
+ {
+ // if return value is string and not auto or none,
+ // return ETrue because auto is used as default value
+ if ( IsStringValueL( aProperty ) && !IsPropertyNone( aProperty ) )
+ {
+ return ETrue;
+ }
+ }
+ return returnValue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsPropertyNone()
+// Check if property is set to NONE.
+// -----------------------------------------------------------------------------
+//
+static TBool IsPropertyNone( CXnProperty& aProperty )
+ {
+ if ( &aProperty )
+ {
+ TInt index = 0;
+ CXnDomProperty* domProperty = aProperty.Property();
+ CXnDomPropertyValue* domPropertyValue =
+ static_cast< CXnDomPropertyValue* >(
+ domProperty->PropertyValueList().Item( index ) );
+ return domPropertyValue->IsNoneIdent();
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsRelativeL()
+// Check if node's positioning is absolute.
+// -----------------------------------------------------------------------------
+//
+static TBool IsRelativeL( CXnNode& aNode )
+ {
+ CXnProperty* positioningProperty = aNode.PositionL();
+ if ( positioningProperty )
+ {
+ const TDesC8& positioning = positioningProperty->StringValue();
+ if ( positioning == XnPropertyNames::style::common::position::KRelative )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsSmallerThanMinSizeL()
+// Check if node rect size is smaller than it's min sizes.
+// -----------------------------------------------------------------------------
+//
+static TBool IsSmallerThanMinSizeL( const TRect& aParentRect, CXnNode& aNode,
+ CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TRect parentRect = aParentRect;
+ CXnProperty* heightproperty = aNode.HeightL();
+ CXnProperty* widthproperty = aNode.WidthL();
+
+ if ( heightproperty )
+ {
+ CXnProperty* minheightproperty = aNode.MinHeightL();
+ if ( minheightproperty )
+ {
+ if ( !IsPropertyNone( *minheightproperty ) )
+ {
+ TInt minheight = VerticalPixelValueL( minheightproperty,
+ parentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
+ TInt height = aNode.Rect().Height();
+ if ( height < minheight )
+ {
+ // height smaller than minimum
+ return ETrue;
+ }
+ }
+ }
+ }
+ if ( widthproperty )
+ {
+ CXnProperty* minwidthproperty = aNode.MinWidthL();
+ if ( minwidthproperty )
+ {
+ if ( !IsPropertyNone( *minwidthproperty ) )
+ {
+ TInt minwidth = HorizontalPixelValueL( minwidthproperty,
+ parentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
+ TInt width = aNode.Rect().Width();
+ if ( width < minwidth )
+ {
+ // width smaller than minimum
+ return ETrue;
+ }
+ }
+ }
+ }
+ // width and height within limits
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsStringValueL()
+// Check if property value is string.
+// -----------------------------------------------------------------------------
+//
+static TBool IsStringValueL( CXnProperty& aProperty )
+ {
+ CXnDomList& propertyValueList = aProperty.Property()->PropertyValueList();
+ CXnDomPropertyValue* value =
+ static_cast< CXnDomPropertyValue* >( propertyValueList.Item( 0 ) );
+ if ( value->PrimitiveValueType() == CXnDomPropertyValue::EString ||
+ value->PrimitiveValueType() == CXnDomPropertyValue::EIdent )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// IsValuePercentageL()
+// Check if property value is percentage.
+// -----------------------------------------------------------------------------
+//
+static TBool IsValuePercentageL( CXnProperty& aProperty )
+ {
+ CXnDomProperty* domProperty = aProperty.Property();
+ CXnDomPropertyValue* domPropertyValue = static_cast<
+ CXnDomPropertyValue* >( domProperty->PropertyValueList().Item( 0 ) );
+ if ( !domPropertyValue )
+ {
+ User::Leave( KXnErrDomPropertyValueNULL );
+ }
+ CXnDomPropertyValue::TPrimitiveValueType valueType =
+ domPropertyValue->PrimitiveValueType();
+ if ( valueType == CXnDomPropertyValue::EPercentage )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// PercentageToPixelsL()
+// Convert percentage value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt PercentageToPixelsL( TReal& aPercentage, TReal aReferenceValue )
+ {
+ TReal value = aReferenceValue * aPercentage * KIntPercentageConstant;
+ return static_cast< TInt >( value + KIntConversionConstant );
+ }
+
+// -----------------------------------------------------------------------------
+// GetPreviousNodeL()
+// -----------------------------------------------------------------------------
+//
+static CXnNode* GetPreviousNodeL( CXnNode& aNode )
+ {
+ CXnNode* returnValue = NULL;
+ CXnNode* parent = aNode.Parent();
+
+ if ( !parent )
+ {
+ return returnValue;
+ }
+
+ RPointerArray< CXnNode >& nodes = parent->Children();
+
+ for ( TInt currentIndex = 0; currentIndex < nodes.Count(); currentIndex++ )
+ {
+ CXnNode* checkNode = nodes[currentIndex];
+ if ( &aNode == checkNode && currentIndex > 0 )
+ {
+ for ( TInt candidateIndex =
+ currentIndex - 1; candidateIndex >= 0; candidateIndex-- )
+ {
+ checkNode = nodes[candidateIndex];
+ if ( IsNodeDisplayedL( *checkNode ) &&
+ !checkNode->IsDropped() && !IsAbsoluteL( *checkNode ) &&
+ !IsNodeTooltip( *checkNode ) )
+ {
+ returnValue = nodes[candidateIndex];
+ break;
+ }
+ }
+ }
+ }
+
+ return returnValue;
+ }
+
+// -----------------------------------------------------------------------------
+// PlaceAreasL()
+// Move the area rects to their places. All positioning is done here.
+// -----------------------------------------------------------------------------
+//
+static void PlaceAreasL( CXnNode& aNode, RPointerArray< CXnNode >& aLaidOutList,
+ TInt aLayoutPhase, CGraphicsDevice& aGraphicsDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
+ {
+ CXnNodeBreadthFirstIterator< CXnNode >* iterator =
+ CXnNodeBreadthFirstIterator< CXnNode >::NewL( aNode );
+ CleanupStack::PushL( iterator );
+
+ RPointerArray< CXnNode > absoluteNodes;
+ CleanupClosePushL( absoluteNodes );
+
+ RPointerArray< CXnNode > relativeNodes;
+ CleanupClosePushL( relativeNodes );
+
+ RPointerArray< CXnNode > autoNodes;
+ CleanupClosePushL( autoNodes );
+
+ RPointerArray< CXnNode > adaptiveNodes;
+ CleanupClosePushL( adaptiveNodes );
+
+ CXnProperty* parentBlockProgressionProperty( NULL );
+ CXnProperty* parentDirectionProperty( NULL );
+ const TDesC8* parentBlockProgression( NULL );
+ const TDesC8* parentDirection( NULL );
+
+ CXnUiEngine* engine( aNode.UiEngine() );
+ TSize maxAvailableSize( engine->ClientRect().Size() );
+
+ // Start to go through the tree
+ CXnNode* previous( NULL );
+
+ CXnNode* parent( NULL );
+ TInt columnWidth;
+ TInt columnMargin;
+ TRect parentRect;
+
+#ifdef _XN3_DEBUG_
+ RDebug::Print( _L("Xuikon: Layout:") );
+ TBuf8< 256 > debug;
+#endif
+
+ // Place areas according their parents and positioning
+ for( CXnNode* node = iterator->Value(); node; node = iterator->NextL() )
+ {
+#ifdef _XN3_DEBUG_
+ debug = node->Type()->Type();
+ CXnProperty* id( node->IdL() );
+ if ( id )
+ {
+ debug.Append( _L8( ", id: " ) );
+ debug.Append( id->StringValue() );
+ }
+#endif
+
+ if ( node->IsLaidOut() )
+ {
+#ifdef _XN3_DEBUG_
+ debug.Append( _L8( ", already laidout" ) );
+ RDebug::RawPrint( debug );
+#endif
+
+ continue;
+ }
+
+ if ( !IsNodeDisplayedL( *node ) || node->IsDropped() )
+ {
+#ifdef _XN3_DEBUG_
+ debug.Append( _L8( ", not displayed or dropped" ) );
+ RDebug::RawPrint( debug );
+#endif
+ continue;
+ }
+
+#ifdef _XN3_DEBUG_
+ RDebug::RawPrint( debug );
+#endif
+
+ switch ( aLayoutPhase )
+ {
+ case XnLayoutPhase::ELayout:
+ if ( aLaidOutList.Find( node ) == KErrNotFound )
+ {
+ aLaidOutList.AppendL( node );
+ }
+ /* flow through */
+ case XnLayoutPhase::EMeasure:
+ if ( node->ViewNodeImpl() )
+ {
+ // check that view's children fit into it
+ FitChildrenIntoParentL( *node, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ continue;
+ }
+ engine->CheckAdaptiveContentL( *node, maxAvailableSize );
+ if ( node->IsDropped() )
+ {
+ // Adaptive content check dropped this node
+ continue;
+ }
+ break;
+ default:
+ // Should not happen
+ continue;
+ }
+
+ if( node->Type()->Type() == KScrollableBoxNodeName )
+ {
+ CXnScrollableControlAdapter* cntrl = node->ScrollableControl();
+ if( cntrl )
+ {
+ cntrl->ResetState();
+ }
+ }
+
+ CXnNode* tmpParent( DisplayedParentL( *node ) );
+
+ // Is parent changed?
+ if ( tmpParent != parent )
+ {
+ columnWidth = 0;
+ columnMargin = 0;
+ if ( parent )
+ {
+ // Process auto areas
+ ProcessAutoAreasL( *parent, &autoNodes, *parentBlockProgression,
+ *parentDirection, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ autoNodes.Reset();
+ // Pocess relative areas
+ for ( TInt i = 0; i < relativeNodes.Count(); i++ )
+ {
+ CalculateRelativePositionsL( parentRect, *relativeNodes[i],
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ relativeNodes.Reset();
+ // Process absolute areas
+ for ( TInt i = 0; i < absoluteNodes.Count(); i++ )
+ {
+ CalculatePaddingL( parentRect, *absoluteNodes[i],
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ CalculateBorderL( *absoluteNodes[i], parentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ CalculateAbsoluteMarginL( *parent, *absoluteNodes[i], NULL,
+ *parentBlockProgression, *parentDirection, parentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ CalculateAbsolutePositionsL( *absoluteNodes[i], parentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ absoluteNodes.Reset();
+ previous = NULL;
+ }
+ // Get new parent properties
+ parent = tmpParent;
+ parentBlockProgressionProperty = parent->BlockProgressionL();
+ parentDirectionProperty = parent->DirectionL();
+ if ( !parentBlockProgressionProperty )
+ {
+ // block progression default is tb
+ parentBlockProgression =
+ &XnPropertyNames::style::common::block_progression::KTB();
+ }
+ else
+ {
+ parentBlockProgression =
+ &parentBlockProgressionProperty->StringValue();
+ }
+ if ( !parentDirectionProperty )
+ {
+ // direction default is ltr
+ parentDirection =
+ &XnPropertyNames::style::common::direction::KLTR();
+ }
+ else
+ {
+ parentDirection = &parentDirectionProperty->StringValue();
+ }
+ }
+
+ parentRect = parent->Rect();
+
+ CalculateRectL( *node, *parent, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+
+ // Which positioning is used?
+ CXnProperty* positioningProp( node->PositionL() );
+ // Static is the default
+ const TDesC8* positioning(
+ &XnPropertyNames::style::common::position::KStatic() );
+
+ if ( positioningProp )
+ {
+ const TDesC8& value( positioningProp->StringValue() );
+ if ( value != KNullDesC8 )
+ {
+ positioning = &value;
+ }
+ }
+ // Adaptive nodes' _must_ be collected here
+ if ( node->IsAdaptive() && adaptiveNodes.Find( node ) == KErrNotFound )
+ {
+ // Postpone adaptive area processing
+ adaptiveNodes.AppendL( node );
+ }
+ // Tooltips are processed as absolute areas
+ TBool absolute( IsAbsoluteL( *node ) || IsNodeTooltip( *node ) );
+ if ( !node->ViewNodeImpl() && HasNodeAutoValuesL( *node ) && !absolute )
+ {
+ // if area has auto values, process it later
+ autoNodes.AppendL( node );
+ }
+ if ( absolute )
+ {
+ // Absolute positioning area found, take it out of normal flow
+ // Because of that, previous node is not set
+ // Absolute area is put to a array to be processed later
+ absoluteNodes.AppendL( node );
+ continue;
+ }
+ // static or relative positioning
+ CalculatePaddingL( parentRect, *node, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ CalculateBorderL( *node, parentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ previous = GetPreviousNodeL( *node );
+ CalculateMarginL( *parent, *node, previous, *parentBlockProgression,
+ *parentDirection, parentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels, columnWidth,
+ columnMargin );
+ FitChildrenIntoParentL( *node, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ if ( XnPropertyNames::style::common::position::KRelative() ==
+ *positioning )
+ {
+ // Relative positioning area found, add it's offset later
+ relativeNodes.AppendL( node );
+ }
+ previous = node;
+ }
+
+ if ( parent )
+ {
+ // Are there auto nodes left?
+ ProcessAutoAreasL( *parent, &autoNodes, *parentBlockProgression,
+ *parentDirection, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ // Are there relative nodes left?
+ for ( TInt i = 0; i < relativeNodes.Count(); i++ )
+ {
+ CalculateRelativePositionsL( parentRect, *relativeNodes[i],
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ // Are there absolute nodes left?
+ for ( TInt i = 0; i < absoluteNodes.Count(); i++ )
+ {
+ CalculatePaddingL( parentRect, *absoluteNodes[i], aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ CalculateBorderL( *absoluteNodes[i], parentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ CalculateAbsoluteMarginL( *parent, *absoluteNodes[i], NULL,
+ *parentBlockProgression, *parentDirection, parentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ FitChildrenIntoParentL( *absoluteNodes[i], aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ CalculateAbsolutePositionsL( *absoluteNodes[i], parentRect,
+ aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ }
+ }
+
+ for ( TInt i = 0; i < adaptiveNodes.Count(); i++ )
+ {
+ // Fix parent size to its childs content size
+ ProcessAdaptiveAreasL( *adaptiveNodes[i], aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ }
+
+ // close node arrays and destroy iterator
+ CleanupStack::PopAndDestroy( 5, iterator );
+ }
+
+// -----------------------------------------------------------------------------
+// PriorizeChildrenL()
+// Find a child node with highest priority value and drop all
+// child nodes with highest priority.
+// -----------------------------------------------------------------------------
+//
+static void PriorizeChildrenL( CXnNode& aNode )
+ {
+ RPointerArray< CXnNode >& children( aNode.Children() );
+
+ CXnNode* candidate( NULL );
+ TInt highest( 0 );
+
+ // Find the highest priority value among the children
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNode* node( children[i] );
+ if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
+ !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
+ {
+ CXnProperty* priorityProperty( node->DisplayPriorityL() );
+ if ( priorityProperty )
+ {
+ TInt priority( priorityProperty->FloatValueL() );
+ if ( priority > highest )
+ {
+ // highest found, set new top priority
+ highest = priority;
+ candidate = node;
+ }
+ }
+ }
+ }
+ if ( candidate )
+ {
+ aNode.UiEngine()->SetNodeDroppedL(
+ *candidate, XnNodeLayout::EDropped );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateAutoPropertiesOfNodesL()
+//
+// -----------------------------------------------------------------------------
+//
+static void CalculateAutoPropertiesOfNodesL(
+ RPointerArray< CXnNode >* aAutoNodeArray, TInt& aWidthAutoCount,
+ TInt& aHeightAutoCount )
+ {
+ aWidthAutoCount = 0;
+ aHeightAutoCount = 0;
+
+ // calculate the number of auto properties in each direction
+ for ( TInt i = 0; i < aAutoNodeArray->Count(); ++i )
+ {
+ CXnNode* tmp = ( *aAutoNodeArray )[i];
+ if ( !tmp->IsDropped() )
+ {
+ if ( HasNodeVerticalAutoValuesL( *tmp ) )
+ {
+ ++aHeightAutoCount;
+ }
+ if ( HasNodeHorizontalAutoValuesL( *tmp ) )
+ {
+ ++aWidthAutoCount;
+ }
+ }
+ }
+ if ( aWidthAutoCount == 0 )
+ {
+ aWidthAutoCount = 1;
+ }
+ if ( aHeightAutoCount == 0 )
+ {
+ aHeightAutoCount = 1;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ProcessAutoAreasL()
+// Process nodes with layout properties defined as auto.
+// -----------------------------------------------------------------------------
+//
+static void ProcessAutoAreasL( CXnNode& aParent,
+ RPointerArray< CXnNode >* aAutoNodeArray,
+ const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TInt autoCount( aAutoNodeArray->Count() );
+
+ if ( autoCount == 0 )
+ {
+ return;
+ }
+
+ // Just to be sure, drop others first if needed
+ FitChildrenIntoParentL( aParent, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+
+ TInt originalHeightAutoCount( 0 );
+ TInt originalWidthAutoCount( 0 );
+
+ CalculateAutoPropertiesOfNodesL( aAutoNodeArray, originalWidthAutoCount,
+ originalHeightAutoCount );
+
+ TInt heightAutoCount( originalHeightAutoCount );
+ TInt widthAutoCount( originalWidthAutoCount );
+
+ // calculate space to use (parent height and width - placed areas)
+ CXnNode* parent( &aParent );
+ TRect parentRect( parent->Rect() );
+
+ if( parent->Control() && parent->Control()->OwnsWindow() )
+ {
+ parentRect = TRect( parentRect.iTl - parent->MarginRect().iTl, parentRect.Size() );
+ }
+
+ TInt parentWidth( parentRect.Width() );
+ TInt parentHeight( parentRect.Height() );
+
+ RPointerArray< CXnNode >& children( parent->Children() );
+
+ RPointerArray< CXnNode > layoutedAutoNodes;
+ CleanupClosePushL( layoutedAutoNodes );
+
+ TBool layoutedAutoNodesAdded( EFalse );
+ TBool layoutingHeight( EFalse );
+ TBool layoutingWidth( EFalse );
+
+ TInt displayedChildCount( DisplayedChildrenCountL( aParent ) );
+
+ do
+ {
+ layoutedAutoNodesAdded = EFalse;
+
+ // count the size used by the non auto nodes and
+ // auto nodes which have been calculated
+ TSize calculatedAutosize = CalculateSpaceUsedByAutoChildrenL(
+ *aAutoNodeArray, layoutedAutoNodes, *parent,
+ aParentBlockProgression, aParentDirection, aGraphicsDevice );
+
+ TInt usedSiblingHeight( calculatedAutosize.iHeight );
+ TInt usedSiblingWidth( calculatedAutosize.iWidth );
+
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ // calculate space for each auto area
+ parentHeight = parentRect.Height() - usedSiblingHeight;
+ parentHeight = parentHeight / heightAutoCount;
+ layoutingHeight = ETrue;
+ }
+ else // assume that block progression is LR or RL
+ {
+ // calculate space for each auto area
+ parentWidth = parentRect.Width() - usedSiblingWidth;
+ parentWidth = parentWidth / widthAutoCount;
+ layoutingWidth = ETrue;
+ }
+ for ( TInt i = 0; i < autoCount; i++ )
+ {
+ CXnNode* node( ( *aAutoNodeArray )[i] );
+ if ( layoutedAutoNodes.Find( node ) != KErrNotFound )
+ {
+ // The size has already been calculated and fixed
+ continue;
+ }
+ if ( node->IsDropped() )
+ {
+ // The node is dropped, no need to recalculate
+ continue;
+ }
+ CXnProperty* heightProperty = node->HeightL();
+ CXnProperty* widthProperty = node->WidthL();
+ CXnProperty* marginLeft = node->MarginLeftL();
+ CXnProperty* marginRight = node->MarginRightL();
+ CXnProperty* marginTop = node->MarginTopL();
+ CXnProperty* marginBottom = node->MarginBottomL();
+ TInt freeHeight = parentHeight;
+ TInt freeWidth = parentWidth;
+ TBool verticalValuesAuto = IsPropertyAutoL( *heightProperty ) ||
+ IsPropertyAutoL( *marginTop ) ||
+ IsPropertyAutoL( *marginBottom );
+ if ( !verticalValuesAuto == !heightProperty )
+ {
+ verticalValuesAuto = ETrue;
+ }
+ TBool horizontalValuesAuto = IsPropertyAutoL( *widthProperty ) ||
+ IsPropertyAutoL( *marginLeft ) ||
+ IsPropertyAutoL( *marginRight );
+ if ( !horizontalValuesAuto == !widthProperty )
+ {
+ horizontalValuesAuto = ETrue;
+ }
+ TInt adaptive( node->IsAdaptive() );
+ // I have childs share the available space between them
+ if ( adaptive & XnAdaptive::EHeight )
+ {
+ // Give all available height to the adaptive node's children
+ freeHeight = parentRect.Height() - usedSiblingHeight;
+ }
+ if ( adaptive & XnAdaptive::EWidth )
+ {
+ // Give all available width to the adaptive node's children
+ freeWidth = parentRect.Width() - usedSiblingWidth;
+ }
+ ScaleAutoAreaL( *node, freeWidth, freeHeight,
+ aParentBlockProgression, aParentDirection,
+ parentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ FitChildrenIntoParentL( *node, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ // handle autonodes which had auto width or height,
+ // but also min or max limit
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ if ( IsPropertyAutoL( *heightProperty ) &&
+ ( freeHeight != node->MarginRect().Height() ) )
+ {
+ if ( layoutedAutoNodes.Find( node ) == KErrNotFound )
+ {
+ // The height has been callculated already
+ // and it doesn't depend on the expected
+ // auto size anymore, mark the node as layouted
+ // and reduce the parent free size
+ layoutedAutoNodes.AppendL( node );
+ heightAutoCount--;
+ layoutedAutoNodesAdded = ETrue;
+ }
+ }
+ }
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ if ( IsPropertyAutoL( *widthProperty ) &&
+ ( freeWidth != node->MarginRect().Width() ) )
+ {
+ if ( layoutedAutoNodes.Find ( node ) == KErrNotFound )
+ {
+ // The width has been callculated already
+ // and it doesn't depend on the expected
+ // auto size anymore, mark the node as layouted
+ // and reduce the parent free size
+ layoutedAutoNodes.AppendL( node );
+ widthAutoCount--;
+ layoutedAutoNodesAdded = ETrue;
+ }
+ }
+ }
+ }
+
+ // drop areas if children don't fit
+ FitAutoChildrenIntoParentL( *aAutoNodeArray, layoutedAutoNodes,
+ *parent, aParentBlockProgression, aParentDirection,
+ aGraphicsDevice );
+
+ // if something was dropped, reset the layouted auto nodes array
+ TInt newDisplayedChildCount = DisplayedChildrenCountL( aParent );
+
+ if ( displayedChildCount != newDisplayedChildCount )
+ {
+ // if nodes with auto values are dropped
+ // recalculate the auto counts
+ CalculateAutoPropertiesOfNodesL( aAutoNodeArray,
+ originalWidthAutoCount, originalHeightAutoCount );
+
+ // recalculate everything again because something was dropped
+ layoutedAutoNodes.Reset();
+ displayedChildCount = newDisplayedChildCount;
+ heightAutoCount = originalHeightAutoCount;
+ widthAutoCount = originalWidthAutoCount;
+ layoutedAutoNodesAdded = ETrue;
+ }
+
+ }
+ while( layoutedAutoNodesAdded && ( ( heightAutoCount && layoutingHeight ) ||
+ ( widthAutoCount && layoutingWidth ) ) );
+
+ MoveAutoAreaL( parentRect, children, aParentBlockProgression,
+ aParentDirection );
+
+ CleanupStack::PopAndDestroy( &layoutedAutoNodes );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateCollapseMarginsL()
+// Return the amount the margins should be collapsed in two list. The list
+// element contains the amount of margins collapsed in pixels to the previous
+// layoutable, nondropped, static and nontooltip node.
+// When calculating the movement of the node, this value should be decreased
+// from the movement.
+// When calculating the total size of the auto proerety nodes, this value
+// should be decreased from the size taken.
+// If the children list contains one of the above mentioned type of nodes,
+// then the value for those are always 0.
+// For example, if there are three children and the middle one has been
+// dropped, the the returned list contains two elemnts, first is 0 and
+// the second one is the amount of collapsed margins between the first and the
+// last node.
+// The caller is responsible of releasing the returned arrays.
+// -----------------------------------------------------------------------------
+//
+static void CalculateCollapseMarginsL( RPointerArray< CXnNode >& aChildren,
+ RArray< TInt >& aCollapsedMarginsWidth,
+ RArray< TInt >& aCollapsedMarginsHeight,
+ const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection )
+ {
+ aCollapsedMarginsWidth.Reset();
+ aCollapsedMarginsHeight.Reset();
+
+ // Find first node which needs to be taken into account
+ CXnNode* previousNode = NULL;
+ TInt startIndex = aChildren.Count();
+ for ( TInt i = 0; !previousNode && i < aChildren.Count(); i++ )
+ {
+ if ( IsNodeDisplayedL( *aChildren[i] ) &&
+ !aChildren[i]->IsDropped() &&
+ !IsAbsoluteL(*aChildren[i]) &&
+ !IsNodeTooltip(*aChildren[i]) &&
+ aChildren[i]->IsLayoutCapable())
+ {
+ previousNode = aChildren[i];
+ startIndex = aChildren.Find( previousNode ) + 1;
+ }
+ }
+
+ // Add needed amount of collapsed margins as 0
+ for ( TInt i = 1; i < startIndex; i++ )
+ {
+ User::LeaveIfError( aCollapsedMarginsWidth.Append( 0 ) );
+ User::LeaveIfError( aCollapsedMarginsHeight.Append( 0 ) );
+ }
+
+ // Calculate collapsed for the rest of the nodes, 0 if not needed
+ for ( TInt i = startIndex; i < aChildren.Count() && previousNode; i++ )
+ {
+ CXnNode* node = aChildren[i];
+ TInt collapsedWidth = 0;
+ TInt collapsedHeight = 0;
+
+ if ( IsNodeDisplayedL( *node ) &&
+ !node->IsDropped() &&
+ !IsAbsoluteL( *node ) &&
+ !IsNodeTooltip( *node ) &&
+ node->IsLayoutCapable() )
+ {
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL ) &&
+ aParentDirection ==
+ XnPropertyNames::style::common::direction::KLTR )
+ {
+ TInt previousRightMargin = Abs( previousNode->
+ MarginRect().iBr.iX - previousNode->BorderRect().iBr.iX );
+ TInt nodeLeftMargin = Abs( node->BorderRect().iTl.iX -
+ node->MarginRect().iTl.iX );
+
+ collapsedWidth = -( previousRightMargin > nodeLeftMargin ) ?
+ nodeLeftMargin : previousRightMargin;
+ }
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ) &&
+ aParentDirection ==
+ XnPropertyNames::style::common::direction::KRTL )
+ {
+ TInt previousLeftMargin = Abs( previousNode->
+ MarginRect().iTl.iX - previousNode->BorderRect().iTl.iX );
+ TInt nodeRightMargin = Abs( node->BorderRect().iBr.iX -
+ node->MarginRect().iBr.iX );
+
+ collapsedWidth = ( previousLeftMargin > nodeRightMargin ) ?
+ nodeRightMargin : previousLeftMargin;
+ }
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT ) &&
+ aParentDirection ==
+ XnPropertyNames::style::common::direction::KLTR )
+ {
+ TInt previousBottomMargin = Abs( previousNode->
+ MarginRect().iBr.iY - previousNode->BorderRect().iBr.iY );
+ TInt nodeTopMargin = Abs( node->BorderRect().iTl.iY -
+ node->MarginRect().iTl.iY );
+
+ collapsedHeight = ( previousBottomMargin > nodeTopMargin ) ?
+ nodeTopMargin : previousBottomMargin;
+ }
+
+ if ( ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT ) &&
+ aParentDirection ==
+ XnPropertyNames::style::common::direction::KRTL )
+ {
+ TInt previousTopMargin = Abs( previousNode->\
+ MarginRect().iTl.iY - previousNode->BorderRect().iTl.iY );
+ TInt nodeBottomMargin = Abs( node->BorderRect().iBr.iY -
+ node->MarginRect().iBr.iY );
+
+ collapsedHeight = -( ( previousTopMargin > nodeBottomMargin ) ?
+ nodeBottomMargin : previousTopMargin );
+ }
+ }
+ User::LeaveIfError( aCollapsedMarginsWidth.Append( collapsedWidth ) );
+ User::LeaveIfError( aCollapsedMarginsHeight.Append( collapsedHeight ) );
+ previousNode = node;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateSpaceUsedByAutoChildrenL()
+// Return space used by node's children including auto nodes which have
+// been calculated.
+// -----------------------------------------------------------------------------
+//
+static TSize CalculateSpaceUsedByAutoChildrenL(
+ RPointerArray< CXnNode >& aAutoChildren,
+ RPointerArray< CXnNode >& aCalculatedAutoChildren,
+ CXnNode& aParent, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, CGraphicsDevice& /*aScreenDevice*/ )
+ {
+ TInt usedSiblingHeight( 0 );
+ TInt usedSiblingWidth( 0 );
+
+ TSize largestSize( 0, 0 );
+
+ // Calculate collapsed margins
+ RArray< TInt > collapsedMarginsWidth;
+ RArray< TInt > collapsedMarginsHeight;
+
+ CleanupClosePushL( collapsedMarginsWidth );
+ CleanupClosePushL( collapsedMarginsHeight );
+
+ RPointerArray< CXnNode >& children( aParent.Children() );
+
+ CalculateCollapseMarginsL( children,
+ collapsedMarginsWidth,
+ collapsedMarginsHeight,
+ aParentBlockProgression,
+ aParentDirection );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNode* node( children[i] );
+ if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
+ !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
+ {
+ // Calculate how much does the node takes space,
+ // 0 is used for auto nodes which have not been calculated
+ TSize siblingSize( node->MarginRect().Size() );
+ if ( aAutoChildren.Find( node ) != KErrNotFound &&
+ aCalculatedAutoChildren.Find( node ) == KErrNotFound )
+ {
+ // Node is auto node and its values have not been fixed yet
+ // The node may have auto in either direction
+ // so that must be checked
+ if ( HasNodeVerticalAutoValuesL( *node ) )
+ {
+ siblingSize.iHeight = 0;
+ }
+ if ( HasNodeHorizontalAutoValuesL( *node ) )
+ {
+ siblingSize.iWidth = 0;
+ }
+ }
+ // Update the largets found node rect
+ if ( siblingSize.iWidth > largestSize.iWidth )
+ {
+ largestSize.iWidth = siblingSize.iWidth;
+ }
+ if ( siblingSize.iHeight > largestSize.iHeight )
+ {
+ largestSize.iHeight = siblingSize.iHeight;
+ }
+ // Add the used area
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ usedSiblingHeight += siblingSize.iHeight;
+ usedSiblingWidth = largestSize.iWidth;
+ }
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ usedSiblingWidth += siblingSize.iWidth;
+ usedSiblingHeight = largestSize.iHeight;
+ }
+ // Find the children index from all children
+ TInt childrenIndex( children.Find( node ) );
+ // No collapsing for just one node
+ if ( childrenIndex > 0 )
+ {
+ // Take the collapsed margins into account
+ // (the value is 0 if not collapsed)
+ usedSiblingWidth -= collapsedMarginsWidth[childrenIndex - 1];
+ usedSiblingHeight -= collapsedMarginsHeight[childrenIndex - 1];
+ }
+ }
+ }
+ // Collapsed arrays
+ CleanupStack::PopAndDestroy( 2 );
+
+ return TSize( usedSiblingWidth, usedSiblingHeight );
+ }
+
+// -----------------------------------------------------------------------------
+// MoveAutoAreaL()
+// Move nodes after all auto properties have been handled.
+// -----------------------------------------------------------------------------
+//
+static void MoveAutoAreaL( TRect& parentRect,
+ RPointerArray< CXnNode >& aChildren, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection )
+ {
+ // Calculate collapsed margins
+ RArray< TInt > collapsedMarginsWidth;
+ RArray< TInt > collapsedMarginsHeight;
+
+ CleanupClosePushL( collapsedMarginsWidth );
+ CleanupClosePushL( collapsedMarginsHeight );
+
+ CalculateCollapseMarginsL( aChildren, collapsedMarginsWidth,
+ collapsedMarginsHeight, aParentBlockProgression,
+ aParentDirection );
+
+ CXnNode* previousNode( NULL );
+ TInt startIndex( aChildren.Count() );
+
+ for ( TInt i = 0; !previousNode && i < aChildren.Count(); i++ )
+ {
+ CXnNode* node( aChildren[i] );
+ if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
+ !IsAbsoluteL (*node ) && !IsNodeTooltip( *node ) )
+ {
+ previousNode = node;
+ startIndex = i + 1;
+ }
+ }
+ if ( !previousNode )
+ {
+ // Collapsed arrays
+ CleanupStack::PopAndDestroy( 2 );
+ return;
+ }
+
+ // Which way are the boxes layouted?
+ //
+ // 1) ltr, tb: 2) ltr, bt: 3) ltr, rl: 4) ltr, lr:
+ // 1 4 3 6 1 2 3 4 5 6
+ // 2 5 2 5 4 5 6 1 2 3
+ // 3 6 1 4
+ //
+ // 5) rtl, tb: 6) rtl, bt: 7) rtl, rl: 8) rtl, lr:
+ // 4 1 6 3 3 2 1 6 5 4
+ // 5 2 5 2 6 5 4 3 2 1
+ // 6 3 4 1
+ //
+
+ TInt layoutType( 0 );
+ if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB )
+ {
+ layoutType = 1;
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ layoutType = 2;
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ layoutType = 3;
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR )
+ {
+ layoutType = 4;
+ }
+ }
+ else if ( aParentDirection ==
+ XnPropertyNames::style::common::direction::KRTL )
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB )
+ {
+ layoutType = 5;
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ layoutType = 6;
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KRL )
+ {
+ layoutType = 7;
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KLR )
+ {
+ layoutType = 8;
+ }
+ }
+ TRect previousContentRect( previousNode->Rect() );
+ TRect previousPaddingRect( previousNode->PaddingRect() );
+ TRect previousBorderRect( previousNode->BorderRect() );
+ TRect previousMarginRect( previousNode->MarginRect() );
+ TRect previousNormalFlowBorderRect( previousNode->NormalFlowBorderRect() );
+ TInt widthToMove = 0;
+ TInt heightToMove = 0;
+
+ // Move the first node to the correct place
+ switch ( layoutType )
+ {
+ case 1:
+ {
+ // Top to parent top
+ heightToMove = parentRect.iTl.iY - previousMarginRect.iTl.iY;
+ }
+ break;
+ case 2:
+ {
+ // Bottom to parent bottom
+ heightToMove = parentRect.iBr.iY - previousMarginRect.iBr.iY;
+ }
+ break;
+ case 3:
+ {
+ // Left to parent left
+ widthToMove = parentRect.iTl.iX - previousMarginRect.iTl.iX;
+ }
+ break;
+ case 4:
+ {
+ heightToMove = parentRect.iBr.iY - previousMarginRect.iBr.iY;
+ widthToMove = parentRect.iTl.iX - previousMarginRect.iTl.iX;
+ }
+ break;
+ case 5: // flow through
+ case 7:
+ {
+ heightToMove = parentRect.iTl.iY - previousMarginRect.iTl.iY;
+ widthToMove = parentRect.iBr.iX - previousMarginRect.iBr.iX;
+ }
+ break;
+ case 6: // flow through
+ case 8:
+ {
+ heightToMove = parentRect.iBr.iY - previousMarginRect.iBr.iY;
+ widthToMove = parentRect.iBr.iX - previousMarginRect.iBr.iX;
+ }
+ break;
+ }
+
+ // Move rects
+ previousContentRect.Move( widthToMove, heightToMove );
+ previousPaddingRect.Move( widthToMove, heightToMove );
+ previousBorderRect.Move( widthToMove, heightToMove );
+ previousMarginRect.Move( widthToMove, heightToMove );
+ previousNormalFlowBorderRect.Move( widthToMove, heightToMove );
+
+ // Set rects
+ previousNode->SetRect( previousContentRect );
+ previousNode->SetPaddingRect( previousPaddingRect );
+ previousNode->SetBorderRect( previousBorderRect );
+ previousNode->SetMarginRect( previousMarginRect );
+ previousNode->SetNormalFlowBorderRect( previousNormalFlowBorderRect );
+
+ for ( TInt i = startIndex; i < aChildren.Count() && previousNode; i++ )
+ {
+ CXnNode* node( aChildren[i] );
+
+ if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
+ !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
+ {
+ // Get rects
+ TRect contentRect( node->Rect() );
+ TRect paddingRect( node->PaddingRect() );
+ TRect borderRect( node->BorderRect() );
+ TRect marginRect( node->MarginRect() );
+ TRect normalFlowBorderRect( node->NormalFlowBorderRect() );
+ previousMarginRect = previousNode->MarginRect();
+
+ widthToMove = 0;
+ heightToMove = 0;
+
+ // Count movements
+ switch ( layoutType )
+ {
+ case 1:
+ {
+ // Move node top to the previous bottom
+ heightToMove = previousMarginRect.iBr.iY - marginRect.iTl.iY;
+ heightToMove -= collapsedMarginsHeight[i - 1];
+ }
+ break;
+ case 2:
+ {
+ // Move node bottom to the previous top
+ heightToMove = previousMarginRect.iTl.iY - marginRect.iBr.iY;
+ heightToMove += collapsedMarginsHeight[i - 1];
+ }
+ break;
+ case 3:
+ {
+ // Move node left to the previous right
+ widthToMove = previousMarginRect.iBr.iX - marginRect.iTl.iX;
+ widthToMove -= collapsedMarginsWidth[i - 1];
+ }
+ break;
+ case 4:
+ {
+ heightToMove = previousMarginRect.iTl.iY - marginRect.iTl.iY;
+ widthToMove = previousMarginRect.iBr.iX - marginRect.iTl.iX;
+ widthToMove -= collapsedMarginsWidth[i - 1];
+ }
+ break;
+ case 5:
+ {
+ // Move node top to the previous bottom
+ heightToMove = previousMarginRect.iBr.iY - marginRect.iTl.iY;
+ heightToMove -= collapsedMarginsHeight[i - 1];
+ widthToMove = previousMarginRect.iTl.iX - marginRect.iTl.iX;
+ }
+ break;
+ case 6:
+ {
+ // Move node bottom to the previous top
+ heightToMove = previousMarginRect.iTl.iY - marginRect.iBr.iY;
+ heightToMove += collapsedMarginsHeight[i - 1];
+ widthToMove = previousMarginRect.iTl.iX - marginRect.iTl.iX;
+ }
+ break;
+ case 7:
+ {
+ // Move node left to the previous right
+ widthToMove = previousMarginRect.iTl.iX - marginRect.iBr.iX;
+ widthToMove += collapsedMarginsWidth[i - 1];
+ }
+ break;
+ case 8:
+ {
+ heightToMove = previousMarginRect.iTl.iY - marginRect.iTl.iY;
+ widthToMove = previousMarginRect.iTl.iX - marginRect.iBr.iX;
+ widthToMove += collapsedMarginsWidth[i - 1];
+ }
+ break;
+ }
+
+ // Move rects
+ contentRect.Move( widthToMove, heightToMove );
+ paddingRect.Move( widthToMove, heightToMove );
+ borderRect.Move( widthToMove, heightToMove );
+ marginRect.Move( widthToMove, heightToMove );
+ normalFlowBorderRect.Move( widthToMove, heightToMove );
+
+ // Set rects
+ node->SetRect( contentRect );
+ node->SetPaddingRect( paddingRect );
+ node->SetBorderRect( borderRect );
+ node->SetMarginRect( marginRect );
+ node->SetNormalFlowBorderRect( normalFlowBorderRect );
+
+ previousNode = node;
+ }
+ }
+
+ // Collapsed arrays
+ CleanupStack::PopAndDestroy( 2 );
+ }
+
+// -----------------------------------------------------------------------------
+// ScaleAutoAreaL()
+// Scale dimensions for areas that have properties set to AUTO.
+// -----------------------------------------------------------------------------
+//
+static TSize ScaleAutoAreaL( CXnNode& aNode, TInt aWidthToFit,
+ TInt aHeightToFit, const TDesC8& aParentBlockProgression,
+ const TDesC8& aParentDirection, TRect& aParentRect,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ // if only one value is auto, it is computed from equality
+ // if width is set to AUTO, all other values become 0
+ // if both margin left and right are set to AUTO, their computed
+ // values are equal
+ TSize sizeOfAutoArea( 0, 0 );
+
+ RArray< TPtrC8 > autoArray;
+ CleanupClosePushL( autoArray );
+
+ CXnProperty* top = aNode.TopL();
+ if ( IsPropertyAutoL( *top ) )
+ {
+ TPtrC8 propertyName = top->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* bottom = aNode.BottomL();
+ if ( IsPropertyAutoL( *bottom ) )
+ {
+ TPtrC8 propertyName = bottom->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* left = aNode.LeftL();
+ if ( IsPropertyAutoL( *left ) )
+ {
+ TPtrC8 propertyName = left->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* right = aNode.RightL();
+ if ( IsPropertyAutoL( *right ) )
+ {
+ TPtrC8 propertyName = right->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* width = aNode.WidthL();
+ if ( IsPropertyAutoL( *width ) )
+ {
+ TPtrC8 propertyName = width->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ if ( !width )
+ {
+ TPtrC8 propertyName = XnPropertyNames::style::common::KWidth();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* height = aNode.HeightL();
+ if ( IsPropertyAutoL( *height ) )
+ {
+ TPtrC8 propertyName = height->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ if ( !height )
+ {
+ TPtrC8 propertyName = XnPropertyNames::style::common::KHeight();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* marginTop = aNode.MarginTopL();
+ if ( IsPropertyAutoL( *marginTop ) )
+ {
+ TPtrC8 propertyName = marginTop->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* marginBottom = aNode.MarginBottomL();
+ if ( IsPropertyAutoL( *marginBottom ) )
+ {
+ TPtrC8 propertyName = marginBottom->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* marginLeft = aNode.MarginLeftL();
+ if ( IsPropertyAutoL( *marginLeft ) )
+ {
+ TPtrC8 propertyName = marginLeft->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+ CXnProperty* marginRight = aNode.MarginRightL();
+ if ( IsPropertyAutoL( *marginRight ) )
+ {
+ TPtrC8 propertyName = marginRight->Property()->Name();
+ autoArray.Append( propertyName );
+ }
+
+ if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ sizeOfAutoArea = TSize( AutoStaticTBL( aNode, aWidthToFit,
+ aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
+ }
+ else // block progression LR
+ {
+ sizeOfAutoArea = TSize( AutoStaticLRL( aNode, aWidthToFit,
+ aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
+ }
+ }
+ else // direction RTL
+ {
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ sizeOfAutoArea = TSize( AutoStaticBTL( aNode, aWidthToFit,
+ aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
+ }
+ else // block progression RL
+ {
+ sizeOfAutoArea = TSize( AutoStaticRLL( aNode, aWidthToFit,
+ aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
+ }
+ }
+
+ // if size not within min&max size limits, resize
+ // (min-size)
+ if ( HasNodeMinSizesL( aNode ) )
+ {
+ if ( IsSmallerThanMinSizeL( aParentRect, aNode, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
+ {
+ GrowToMinSizeL( aNode, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ }
+ }
+
+ if ( HasNodeMaxSizesL( aNode ) )
+ {
+ if ( IsLargerThanMaxSizeL( aParentRect, aNode, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
+ {
+ ShrinkToMaxSizeL( aNode, aParentRect, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &autoArray );
+
+ // Return the context rect size because the min-max
+ // test might have changed the size of autoarea
+ return aNode.Rect().Size();
+ }
+
+// -----------------------------------------------------------------------------
+// GrowToMinSizeL()
+//
+// -----------------------------------------------------------------------------
+//
+static void GrowToMinSizeL( CXnNode& aNode, TRect& aParentRect,
+ CGraphicsDevice& aScreenDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
+ {
+ // grow to min size
+ CXnProperty* minWidthProperty = aNode.MinWidthL();
+ CXnProperty* minHeightProperty = aNode.MinHeightL();
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+
+ if ( minWidthProperty )
+ {
+ if ( !IsPropertyNone( *minWidthProperty ) )
+ {
+ TInt minWidth = HorizontalPixelValueL( minWidthProperty,
+ aParentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
+ if ( contentRect.Width() < minWidth )
+ {
+ TInt widthToGrow = minWidth - contentRect.Width();
+ contentRect.Resize( widthToGrow, 0 );
+ paddingRect.Resize( widthToGrow, 0 );
+ borderRect.Resize( widthToGrow, 0 );
+ normalFlowBorderRect.Resize( widthToGrow, 0 );
+ marginRect.Resize( widthToGrow, 0 );
+ }
+ }
+ }
+
+ if ( minHeightProperty )
+ {
+ if ( !IsPropertyNone( *minHeightProperty ) )
+ {
+ TInt minHeight = VerticalPixelValueL( minHeightProperty,
+ aParentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
+ if ( contentRect.Height() < minHeight )
+ {
+ TInt heightToGrow = minHeight - contentRect.Height();
+ contentRect.Resize( 0, heightToGrow );
+ paddingRect.Resize( 0, heightToGrow );
+ borderRect.Resize( 0, heightToGrow );
+ normalFlowBorderRect.Resize( 0, heightToGrow );
+ marginRect.Resize( 0, heightToGrow );
+ }
+ }
+ }
+
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ aNode.SetMarginRect( marginRect );
+ }
+
+// -----------------------------------------------------------------------------
+// ShrinkToMaxSizeL()
+// -----------------------------------------------------------------------------
+//
+static void ShrinkToMaxSizeL( CXnNode& aNode, TRect& aParentRect,
+ CGraphicsDevice& aScreenDevice,
+ TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
+ {
+ // grow to min size
+ CXnProperty* maxWidthProperty = aNode.MaxWidthL();
+ CXnProperty* maxHeightProperty = aNode.MaxHeightL();
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+
+ if ( maxWidthProperty )
+ {
+ if ( !IsPropertyNone( *maxWidthProperty ) )
+ {
+ TInt maxWidth = HorizontalPixelValueL( maxWidthProperty,
+ aParentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
+ if ( contentRect.Width() > maxWidth )
+ {
+ TInt widthToShrink = contentRect.Width() - maxWidth;
+ contentRect.Resize( -widthToShrink, 0 );
+ paddingRect.Resize( -widthToShrink, 0 );
+ borderRect.Resize( -widthToShrink, 0 );
+ normalFlowBorderRect.Resize( -widthToShrink, 0 );
+ marginRect.Resize( -widthToShrink, 0 );
+ }
+ }
+ }
+
+ if ( maxHeightProperty )
+ {
+ if ( !IsPropertyNone( *maxHeightProperty ) )
+ {
+ TInt maxHeight = VerticalPixelValueL( maxHeightProperty,
+ aParentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
+ if ( contentRect.Height() > maxHeight )
+ {
+ TInt heightToShrink = contentRect.Height() - maxHeight;
+ contentRect.Resize( 0, -heightToShrink );
+ paddingRect.Resize( 0, -heightToShrink );
+ borderRect.Resize( 0, -heightToShrink );
+ normalFlowBorderRect.Resize( 0, -heightToShrink );
+ marginRect.Resize( 0, -heightToShrink );
+ }
+ }
+ }
+
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+ aNode.SetMarginRect( marginRect );
+ }
+
+// -----------------------------------------------------------------------------
+// FitAutoChildrenIntoParentL()
+//
+// -----------------------------------------------------------------------------
+//
+static void FitAutoChildrenIntoParentL( RPointerArray< CXnNode >& aAutoChildren,
+ RPointerArray< CXnNode >& aCalculatedAutoChildren, CXnNode& aParent,
+ const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
+ CGraphicsDevice& aGraphicsDevice )
+ {
+ if( IsSrollableBox( aParent ) )
+ {
+ return;
+ }
+
+ TSize space = CalculateSpaceUsedByAutoChildrenL( aAutoChildren,
+ aCalculatedAutoChildren, aParent, aParentBlockProgression,
+ aParentDirection, aGraphicsDevice );
+
+ TSize parentSize( aParent.Rect().Size() );
+
+ while( ( ( parentSize.iHeight < space.iHeight ) &&
+ ( parentSize.iHeight > 0 ) ) ||
+ ( ( parentSize.iWidth < space.iWidth ) &&
+ ( parentSize.iWidth > 0 ) ) )
+ {
+ // if areas go over just one pixel, cut the pixel
+ // from a percent sized node
+ if ( ( parentSize.iHeight == space.iHeight - 1 ) ||
+ ( parentSize.iWidth == space.iWidth - 1 ) )
+ {
+ CutOnePixelFromPercentChildNodeL( aParent, aParentBlockProgression );
+ return;
+ }
+
+ TInt childCount( DisplayedChildrenCountL( aParent ) );
+
+ PriorizeChildrenL( aParent );
+
+ if ( DisplayedChildrenCountL( aParent ) == childCount )
+ {
+ // cannot drop any more children, but they still don't fit
+ return;
+ }
+
+ space = CalculateSpaceUsedByAutoChildrenL( aAutoChildren,
+ aCalculatedAutoChildren, aParent, aParentBlockProgression,
+ aParentDirection, aGraphicsDevice );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalCentimetersToPixelsL()
+// Convert vertical centimeter value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalCentimetersToPixelsL( TReal& aCentimeters,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aCentimeters * KCentimetersAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.VerticalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalInchesToPixelsL()
+// Convert vertical inch value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalInchesToPixelsL( TReal& aInches,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aInches * KInchesAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.VerticalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalMillimetersToPixelsL()
+// Convert vertical millimeter value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalMillimetersToPixelsL( TReal& aMillimeters,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aMillimeters * KMillimetersAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.VerticalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalPicasToPixelsL()
+// Convert vertical pica value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalPicasToPixelsL( TReal& aPicas,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aPicas * KPicasAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.VerticalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalPixelValueL()
+// Convert vertical property to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
+ CGraphicsDevice& aScreenDevice, TReal aVerticalUnitInPixels )
+ {
+ return VerticalValueToPixelsL( DomPropertyValueFromProperty( aValue ),
+ static_cast< TReal >( aReferenceValue ), aScreenDevice,
+ aVerticalUnitInPixels );
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalPointsToPixelsL()
+// Convert vertical point value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalPointsToPixelsL( TReal& aPoints,
+ CGraphicsDevice& aScreenDevice )
+ {
+ TReal twips = aPoints * KPointsAsTwips;
+ TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
+ return aScreenDevice.VerticalTwipsToPixels( intTwips );
+ }
+
+// -----------------------------------------------------------------------------
+// VerticalValueToPixelsL()
+// Convert vertical property value to pixel value.
+// -----------------------------------------------------------------------------
+//
+static TInt VerticalValueToPixelsL( CXnDomPropertyValue* aValue,
+ TReal aReferenceValue, CGraphicsDevice& aScreenDevice,
+ TReal aVerticalUnitInPixels )
+ {
+ if ( !aValue )
+ {
+ User::Leave( KXnErrDomPropertyValueNULL );
+ }
+ CXnDomPropertyValue::TPrimitiveValueType valueType =
+ aValue->PrimitiveValueType();
+ // Handle error cases first, inherit is handled elsewhere, none returns 0
+ switch ( valueType )
+ {
+ case CXnDomPropertyValue::EUnknown:
+ case CXnDomPropertyValue::EEms:
+ case CXnDomPropertyValue::EExs:
+ case CXnDomPropertyValue::EDeg:
+ case CXnDomPropertyValue::ERad:
+ case CXnDomPropertyValue::EGrad:
+ case CXnDomPropertyValue::EMs:
+ case CXnDomPropertyValue::ES:
+ case CXnDomPropertyValue::EHz:
+ case CXnDomPropertyValue::EKHz:
+ case CXnDomPropertyValue::EDimension:
+ case CXnDomPropertyValue::EString:
+ case CXnDomPropertyValue::EUri:
+ case CXnDomPropertyValue::EIdent:
+ case CXnDomPropertyValue::EAttr:
+ case CXnDomPropertyValue::ECounter:
+ case CXnDomPropertyValue::ERect:
+ case CXnDomPropertyValue::ERgbColor:
+ case CXnDomPropertyValue::ERgbaColor:
+ case CXnDomPropertyValue::EFunction:
+ break;
+ default:
+ {
+ TReal value = aValue->FloatValueL();
+ if ( valueType == CXnDomPropertyValue::ENumber ||
+ valueType == CXnDomPropertyValue::EPx )
+ {
+ return static_cast< TInt >( value );
+ }
+ else if ( valueType == CXnDomPropertyValue::EPercentage )
+ {
+ return PercentageToPixelsL( value, aReferenceValue );
+ }
+ else if ( valueType == CXnDomPropertyValue::EIn )
+ {
+ return VerticalInchesToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::ECm )
+ {
+ return VerticalCentimetersToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EMm )
+ {
+ return VerticalMillimetersToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EPt )
+ {
+ return VerticalPointsToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EPc )
+ {
+ return VerticalPicasToPixelsL( value, aScreenDevice );
+ }
+ else if ( valueType == CXnDomPropertyValue::EUnitValue )
+ {
+ return VerticalUnitsToPixelsL( value, aVerticalUnitInPixels );
+ }
+ }
+ break;
+ }
+
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// ProcessAdaptiveAreasL()
+// Process adaptive areas
+// -----------------------------------------------------------------------------
+//
+static void ProcessAdaptiveAreasL( CXnNode& aParent,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ CXnProperty* blockProgressionProperty( aParent.BlockProgressionL() );
+ CXnProperty* directionProperty( aParent.DirectionL() );
+ const TDesC8* blockProgression(
+ &XnPropertyNames::style::common::block_progression::KTB() );
+ const TDesC8* direction(
+ &XnPropertyNames::style::common::direction::KLTR() );
+
+ if ( directionProperty )
+ {
+ direction = &directionProperty->StringValue();
+ }
+
+ if ( blockProgressionProperty )
+ {
+ blockProgression = &blockProgressionProperty->StringValue();
+ }
+
+ CalculateAdaptiveSizeL( aParent, *blockProgression, *direction,
+ aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ }
+
+// -----------------------------------------------------------------------------
+// CalculateAdaptiveSizeL()
+// Fixes the adaptive node size to its layouted children size
+// -----------------------------------------------------------------------------
+//
+static void CalculateAdaptiveSizeL( CXnNode& aNode,
+ const TDesC8& aParentBlockProgression, const TDesC8& /*aParentDirection*/,
+ CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
+ TReal aVerticalUnitInPixels )
+ {
+ TInt adaptive( aNode.IsAdaptive() );
+ CXnNode* parent( aNode.Parent() );
+
+ if ( !adaptive || !parent )
+ {
+ return;
+ }
+
+ TInt adaptiveHeight( 0 );
+ TInt adaptiveWidth( 0 );
+
+ RPointerArray< CXnNode > children;
+ CleanupClosePushL( children );
+
+ TInt count( DisplayedChildrenCountL( aNode, &children ) );
+
+ TSize size;
+
+ if ( count == 0 )
+ {
+ TRect parentRect( parent->Rect() );
+ if( parent->Control() && parent->Control()->OwnsWindow() )
+ {
+ parentRect = TRect( parentRect.iTl - parent->MarginRect().iTl, parentRect.Size() );
+ }
+ // I don't have any displayed childrens, fix my own size
+ size = CalculateTotalDimensionsL( aNode, ETrue, EFalse,
+ parentRect, aGraphicsDevice, aHorizontalUnitInPixels,
+ aVerticalUnitInPixels );
+ adaptiveHeight = size.iHeight;
+ adaptiveWidth = size.iWidth;
+ }
+ else
+ {
+ TBool autoHeight( EFalse );
+ TBool autoWidth( EFalse );
+ TBool sizeKnown( EFalse );
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ CXnNode* node( children[i] );
+ if ( !IsNodeDisplayedL( *node ) )
+ {
+ continue;
+ }
+ CXnProperty* heightProperty( node->HeightL() );
+ if ( !( node->IsAdaptive() & XnAdaptive::EHeight ) &&
+ ( adaptive & XnAdaptive::EHeight ) &&
+ IsPropertyAutoL( *heightProperty ) )
+ {
+ adaptiveHeight = node->MarginRect().Size().iHeight;
+ autoHeight = ETrue;
+ if ( !( adaptive & XnAdaptive::EWidth ) )
+ {
+ // Height is now known and width is not adaptive
+ // -> size is now known
+ sizeKnown = ETrue;
+ }
+ }
+ CXnProperty* widthProperty( node->WidthL() );
+ if ( !( node->IsAdaptive() & XnAdaptive::EWidth ) &&
+ ( adaptive & XnAdaptive::EWidth ) &&
+ IsPropertyAutoL( *widthProperty ) )
+ {
+ adaptiveWidth = node->MarginRect().Size().iWidth;
+ autoWidth = ETrue;
+ if ( !( adaptive & XnAdaptive::EHeight ) )
+ {
+ // Width is now known and height is not adaptive
+ // -> size is now known
+ sizeKnown = ETrue;
+ }
+ }
+ if ( autoWidth && autoHeight )
+ {
+ // Both auto -> size is now known
+ sizeKnown = ETrue;
+ }
+ if ( !sizeKnown )
+ {
+ // Fix adaptive sized child's size first
+ ProcessAdaptiveAreasL( *node, aGraphicsDevice,
+ aHorizontalUnitInPixels, aVerticalUnitInPixels );
+ TSize marginSize( node->MarginRect().Size() );
+ if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KTB ||
+ aParentBlockProgression ==
+ XnPropertyNames::style::common::block_progression::KBT )
+ {
+ if ( !autoHeight && ( adaptive & XnAdaptive::EHeight ) )
+ {
+ adaptiveHeight += marginSize.iHeight;
+ }
+ if ( !autoWidth && ( adaptive & XnAdaptive::EWidth ) )
+ {
+ if ( marginSize.iWidth > adaptiveWidth )
+ {
+ adaptiveWidth = marginSize.iWidth;
+ }
+ }
+ }
+ else if ( aParentBlockProgression ==
+ XnPropertyNames::style::common::
+ block_progression::KLR || aParentBlockProgression ==
+ XnPropertyNames::style::common::
+ block_progression::KRL )
+ {
+ if ( !autoHeight && ( adaptive & XnAdaptive::EHeight ) )
+ {
+ if ( marginSize.iHeight > adaptiveHeight )
+ {
+ adaptiveHeight = marginSize.iHeight;
+ }
+ }
+ if ( !autoWidth && ( adaptive & XnAdaptive::EWidth ) )
+ {
+ adaptiveWidth += marginSize.iWidth;
+ }
+ }
+ }
+ }
+ }
+
+ TRect contentRect( aNode.Rect() );
+ TRect paddingRect( aNode.PaddingRect() );
+ TRect borderRect( aNode.BorderRect() );
+ TRect marginRect( aNode.MarginRect() );
+ TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
+
+ TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
+ TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
+ TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
+ TRect normalFlowBorderRectDiff( SubtractRect(
+ normalFlowBorderRect, contentRect ) );
+
+ TInt dy( 0 );
+ TInt dx( 0 );
+
+ if ( adaptive & XnAdaptive::EHeight )
+ {
+ if ( adaptiveHeight <= 0 )
+ {
+ adaptiveHeight = 0;
+ }
+ dy = contentRect.Size().iHeight - adaptiveHeight;
+ }
+ if ( adaptive & XnAdaptive::EWidth )
+ {
+ if ( adaptiveWidth <= 0 )
+ {
+ adaptiveWidth = 0;
+ }
+ dx = contentRect.Size().iWidth - adaptiveWidth;
+ }
+
+ contentRect.Resize( -dx, -dy );
+
+ paddingRect = AddRect( contentRect, paddingRectDiff );
+ borderRect = AddRect( contentRect, borderRectDiff );
+ marginRect = AddRect( contentRect, marginRectDiff );
+ normalFlowBorderRect = AddRect( contentRect, normalFlowBorderRectDiff );
+
+ aNode.SetRect( contentRect );
+ aNode.SetPaddingRect( paddingRect );
+ aNode.SetBorderRect( borderRect );
+ aNode.SetMarginRect( marginRect );
+ aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
+
+ aNode.FixAdaptiveSizeL( contentRect.Size() );
+
+ aNode.UiEngine()->CheckAdaptiveContentL( aNode, contentRect.Size() );
+
+ CleanupStack::PopAndDestroy( &children );
+ }
+
+// -----------------------------------------------------------------------------
+// BuildTriggerNodeLC
+// Builds a trigger node
+// -----------------------------------------------------------------------------
+//
+static CXnNode* BuildTriggerNodeLC( CXnUiEngine& aUiEngine,
+ const TDesC8& aTriggerName )
+ {
+ CXnNode* node = CXnNode::NewL();
+ CleanupStack::PushL( node );
+
+ CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger );
+ CleanupStack::PushL( type );
+
+ CXnNodeImpl* impl = CXnNodeImpl::NewL( type );
+ CleanupStack::Pop( type );
+
+ node->SetImpl( impl );
+ node->SetUiEngine( aUiEngine );
+
+ CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL(
+ aUiEngine.ODT()->DomDocument().StringPool() );
+
+ CleanupStack::PushL( nameValue );
+
+ nameValue->SetStringValueL( CXnDomPropertyValue::EString, aTriggerName );
+
+ CXnProperty* name = CXnProperty::NewL(
+ XnPropertyNames::action::trigger::KName,
+ nameValue, aUiEngine.ODT()->DomDocument().StringPool() );
+
+ CleanupStack::Pop( nameValue );
+
+ CleanupStack::PushL( name );
+
+ node->SetPropertyL( name );
+
+ CleanupStack::Pop( name );
+
+ //CleanupStack::Pop( node );
+
+ return node;
+ }
+
+// -----------------------------------------------------------------------------
+// UpdateInternalUnits
+// Updates UiEngineImpl unit values
+// -----------------------------------------------------------------------------
+//
+static void UpdateInternalUnits( TReal& aHorizontalUnitInPixels,
+ TReal& aVerticalUnitInPixels, TRect aRect )
+ {
+ TAknWindowComponentLayout referenceLayout =
+ AknLayoutScalable_Avkon::aid_value_unit2();
+ TRect parent( aRect );
+
+ TAknLayoutRect rect;
+
+ // TAknWindowLineLayout should go directly
+ //to LayoutRect/LayoutControl etc. methods
+ rect.LayoutRect( parent, referenceLayout.LayoutLine() );
+
+ TReal rectWidth = rect.Rect().Width();
+
+ if ( rectWidth == 0 )
+ {
+ aHorizontalUnitInPixels = 0;
+ }
+
+ aHorizontalUnitInPixels = rectWidth / 10;
+
+ TReal rectHeight = rect.Rect().Height();
+
+ if ( rectHeight == 0 )
+ {
+ aVerticalUnitInPixels = 0;
+ }
+
+ aVerticalUnitInPixels = rectHeight / 10;
+ }
+
+// -----------------------------------------------------------------------------
+// BuildScreenDeviceChangeTriggerNodeLC
+// Build trigger node for screen device change event
+// -----------------------------------------------------------------------------
+//
+static CXnNode* BuildScreenDeviceChangeTriggerNodeLC( CXnUiEngine& aUiEngine )
+ {
+ CXnDomStringPool& sp( aUiEngine.ODT()->DomDocument().StringPool() );
+
+ CXnNode* node = CXnNode::NewL();
+ CleanupStack::PushL( node );
+
+ CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger );
+ CleanupStack::PushL( type );
+
+ CXnNodeImpl* impl = CXnNodeImpl::NewL( type );
+ CleanupStack::Pop( type );
+
+ node->SetImpl( impl );
+ node->SetUiEngine( aUiEngine );
+
+ CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( sp );
+ CleanupStack::PushL( nameValue );
+
+ nameValue->SetStringValueL( CXnDomPropertyValue::EString,
+ XnPropertyNames::action::trigger::name::KScreenDeviceChange );
+
+ CXnProperty* name = CXnProperty::NewL(
+ XnPropertyNames::action::trigger::KName, nameValue, sp );
+ CleanupStack::Pop( nameValue );
+ CleanupStack::PushL( name );
+
+ node->SetPropertyL( name );
+ CleanupStack::Pop( name );
+
+ CXnDomPropertyValue* reasonValue = CXnDomPropertyValue::NewL( sp );
+ CleanupStack::PushL( reasonValue );
+
+ const TDesC8* reasonString( NULL );
+
+ if ( Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ reasonString = &XnPropertyNames::action::trigger::name::
+ uidefinitionmodification::reason::KLandscape;
+ }
+ else
+ {
+ reasonString = &XnPropertyNames::action::trigger::name::
+ uidefinitionmodification::reason::KPortrait;
+ }
+
+ reasonValue->SetStringValueL( CXnDomPropertyValue::EString, *reasonString );
+
+ CXnProperty* reason = CXnProperty::NewL( XnPropertyNames::action::trigger::
+ name::uidefinitionmodification::KReason, reasonValue, sp );
+
+ CleanupStack::Pop( reasonValue );
+
+ CleanupStack::PushL( reason );
+
+ node->SetPropertyL( reason );
+
+ CleanupStack::Pop( reason );
+
+ return node;
+ }
+
+// -----------------------------------------------------------------------------
+// FillFocusCandidatesL
+// -----------------------------------------------------------------------------
+//
+static void FillFocusCandidatesL( CXnNode* aParent,
+ RPointerArray< CXnNode >& aArray )
+ {
+ RPointerArray< CXnNode >& children( aParent->Children() );
+
+ aArray.AppendL( aParent );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ FillFocusCandidatesL( children[i], aArray );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DetermineStatusPaneLayout
+// -----------------------------------------------------------------------------
+//
+static TInt DetermineStatusPaneLayout( CXnProperty* aProperty )
+ {
+ TInt spane( KErrNotFound );
+
+ if ( aProperty )
+ {
+ const TDesC8& value( aProperty->StringValue() );
+
+ // Currently supported status pane layout
+ if ( value == XnPropertyNames::view::statuspanelayout::KNone )
+ {
+ spane = R_AVKON_STATUS_PANE_LAYOUT_EMPTY;
+ }
+ if ( value == XnPropertyNames::view::statuspanelayout::KBasic )
+ {
+ spane = R_AVKON_STATUS_PANE_LAYOUT_IDLE;
+ }
+ else if ( value == XnPropertyNames::view::statuspanelayout::KBasicFlat )
+ {
+ spane = R_AVKON_STATUS_PANE_LAYOUT_IDLE_FLAT;
+ }
+ else if ( value ==
+ XnPropertyNames::view::statuspanelayout::KWideScreen )
+ {
+ spane = R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE;
+ }
+ else if ( value ==
+ XnPropertyNames::view::statuspanelayout::KWideScreenFlat )
+ {
+ spane = R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT;
+ }
+ else if ( value ==
+ XnPropertyNames::view::statuspanelayout::
+ KWideScreenFlat3Softkeys )
+ {
+ spane = R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT_NO_SOFTKEYS;
+ }
+ }
+
+ return spane;
+ }
+
+// -----------------------------------------------------------------------------
+// SetAdaptivesL
+// -----------------------------------------------------------------------------
+//
+static TBool SetAdaptivesL( CXnNode& aNode )
+ {
+ TBool retval( EFalse );
+
+ // Check if the node is adaptive
+ if ( aNode.IsAdaptive( ETrue ) && IsNodeDisplayedL( aNode ) )
+ {
+ retval = ETrue;
+ // Mark adaptive node to be measured
+ aNode.SetAdaptiveL( XnAdaptive::EMeasure );
+ }
+
+ RPointerArray< CXnNode >& children( aNode.Children() );
+
+ for ( TInt i = 0; i < children.Count(); i++ )
+ {
+ TBool ret( SetAdaptivesL( *children[i] ) );
+ if ( ret )
+ {
+ retval = ret;
+ }
+ }
+
+ return retval;
+ }
+
+#ifdef _XN3_DEBUG_
+// -----------------------------------------------------------------------------
+// TraceTreeL
+// -----------------------------------------------------------------------------
+//
+static void TraceTreeL( CXnNode* aRootNode )
+ {
+ CXnDepthFirstTreeIterator< CXnNode >* iterator =
+ CXnDepthFirstTreeIterator< CXnNode >::NewL( *aRootNode );
+ CleanupStack::PushL( iterator );
+
+ RDebug::Print( _L("Xuikon: UI tree:") );
+
+ TBuf8< 256 > debug;
+
+ TInt level( 0 );
+
+ for( CXnNode* node = iterator->Value(); node;
+ node = iterator->NextL() )
+ {
+ debug = _L8( "Xuikon: " );
+
+ level = iterator->Level();
+
+ for ( TInt i = 0; i < level; i++ )
+ {
+ debug.Append( ' ' );
+ }
+
+ debug.Append( node->Type()->Type() );
+
+ CXnProperty* id( node->IdL() );
+
+ if ( id )
+ {
+ debug.Append( _L8( ", id: " ) );
+ debug.Append( id->StringValue() );
+ }
+
+ debug.AppendFormat( _L8( ", laidout: %d" ), node->IsLaidOut() );
+ debug.AppendFormat( _L8( ", displayed: %d" ),
+ IsNodeDisplayedL( *node ) );
+
+ CCoeControl* control( node->Control() );
+
+ if ( control )
+ {
+ TBool visible( control->IsVisible() );
+ TRect rect( control->Rect() );
+ TPoint tl( rect.iTl );
+ TPoint br( rect.iBr );
+ debug.AppendFormat( _L8( ", visible %d:" ), visible );
+ debug.AppendFormat(
+ _L8( ", Tl: %d %d, Br: %d %d" ), tl.iX, tl.iY, br.iX, br.iY );
+ }
+ else
+ {
+ debug.Append( _L8( ", no control" ) );
+ }
+ RDebug::RawPrint( debug );
+ }
+
+ CleanupStack::PopAndDestroy( iterator );
+ }
+#endif
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::CXnUiEngineImpl()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CXnUiEngineImpl::CXnUiEngineImpl( CXnUiEngine& aUiEngine,
+ CXnAppUiAdapter& aAdapter )
+ : iUiEngine( &aUiEngine ), iAppUiAdapter( aAdapter ),
+ iViewManager( aAdapter.ViewManager() )
+ {
+ iAppUiAdapter.UiStateListener().AddObserver( *this );
+
+ iViewManager.AddObserver( *this );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::ConstructL()
+ {
+ iEditMode = CXnEditMode::NewL( *iUiEngine );
+
+ iHitTest = CXnHitTest::NewL();
+
+ iCurrentGraphicsDevice = CCoeEnv::Static()->ScreenDevice();
+
+ // Update the units here, even the refence client rect is only a quess.
+ // That is because we don't know the UI furniture yet. Units are
+ // needed in controls constructions
+ UpdateInternalUnits(
+ iHorizontalUnitInPixels,
+ iVerticalUnitInPixels,
+ iAppUiAdapter.ClientRect() );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CXnUiEngineImpl* CXnUiEngineImpl::NewL( CXnUiEngine& aUiEngine,
+ CXnAppUiAdapter& aAdapter )
+ {
+ return new ( ELeave ) CXnUiEngineImpl( aUiEngine, aAdapter );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::~CXnUiEngineImpl()
+// C++ default destructor.
+// -----------------------------------------------------------------------------
+//
+CXnUiEngineImpl::~CXnUiEngineImpl()
+ {
+ iAppUiAdapter.UiStateListener().RemoveObserver( *this );
+
+ iViewManager.RemoveObserver( *this );
+
+ delete iEditMode;
+ delete iHitTest;
+
+ iFocusCandidateList.Reset();
+ iRedrawRegions.ResetAndDestroy();
+ iDirtyList.Reset();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::AppUiAdapter()
+// -----------------------------------------------------------------------------
+//
+CXnAppUiAdapter& CXnUiEngineImpl::AppUiAdapter() const
+ {
+ return iAppUiAdapter;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::LayoutUIL()
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::LayoutUIL( CXnNode* /*aNode*/ )
+ {
+ if ( IsLayoutDisabled() )
+ {
+ iLayoutControl |= XnLayoutControl::ELayoutUI;
+ return;
+ }
+
+ iLayoutControl &= ~XnLayoutControl::ELayoutUI;
+
+ if ( iDirtyList.Count() == 0 )
+ {
+ // Nothing to do, layout is up-to-date
+ return;
+ }
+
+ DisableRenderUiLC();
+ CXnNode* candidate( StartLayoutFromL() );
+ PrepareRunLayoutL();
+ iDirtyList.Reset();
+
+ // Run layout until it is fully calculated
+ do
+ {
+ iLayoutPhase = RunLayoutL( candidate );
+ }
+ while ( iLayoutPhase != XnLayoutPhase::ENone );
+
+ CXnNode* focused( FocusedNode() );
+
+ if ( focused && focused->IsDropped() )
+ {
+ // The currently focused node is dropped, run losevisualization
+ CXnNode* loseVisualisation =
+ BuildTriggerNodeLC( *iUiEngine,
+ XnPropertyNames::action::trigger::name::KLoseVisualisation );
+
+ focused->ReportXuikonEventL( *loseVisualisation );
+ CleanupStack::PopAndDestroy( loseVisualisation );
+
+ if ( FocusedNode() == focused )
+ {
+ // Remove focus as losevisualization trigger didn't
+ // change focus from dropped node to another one
+ SetFocusedNodeL( NULL );
+ }
+ }
+
+ if ( !FocusedNode() && iAppUiAdapter.FocusShown() )
+ {
+ // No focus, try if some of the focus candidates can be focused
+ RootNode()->RunFocusChangeL( iFocusCandidateList );
+ }
+
+ iFocusCandidateList.Reset();
+
+ iAppUiAdapter.EffectManager()->UiLayouted();
+
+ // Layout is now recalculated
+ CleanupStack::PopAndDestroy(); // anonymous
+ }
+
+// -----------------------------------------------------------------------------
+// PrepareRunLayoutL()
+// Set dropped flags of all nodes in the tree to ENone.
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::PrepareRunLayoutL()
+ {
+ if ( iLayoutPhase == XnLayoutPhase::ENone )
+ {
+ iLayoutPhase = XnLayoutPhase::ELayout;
+
+ for ( TInt i = 0; i < iDirtyList.Count(); i++ )
+ {
+ CXnNode* dirty( iDirtyList[i] );
+
+ // Clear dropped flags recursively
+ SetNodeDroppedL( *dirty, XnNodeLayout::ENone );
+
+ if ( SetAdaptivesL( *dirty ) )
+ {
+ // Adaptive node causes measure phase
+ iLayoutPhase = XnLayoutPhase::EMeasure;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::RunLayoutL()
+// -----------------------------------------------------------------------------
+//
+TInt CXnUiEngineImpl::RunLayoutL( CXnNode* aNode )
+ {
+ TRect clientRect( ClientRect() );
+ // Move it to 0, 0
+ clientRect.Move( -clientRect.iTl.iX, -clientRect.iTl.iY );
+
+ RPointerArray< CXnNode > laidOutList;
+ CleanupClosePushL( laidOutList );
+
+ if ( IsNodeDisplayedL( *aNode ) )
+ {
+ if ( aNode->ViewNodeImpl() && !aNode ->IsLaidOut() )
+ {
+ aNode->SetMarginRect( clientRect );
+ aNode->SetBorderRect( clientRect );
+ aNode->SetNormalFlowBorderRect( clientRect );
+ aNode->SetPaddingRect( clientRect );
+ aNode->SetRect( clientRect );
+ }
+
+ // Put areas to place
+ PlaceAreasL( *aNode, laidOutList, iLayoutPhase,
+ *iCurrentGraphicsDevice, iHorizontalUnitInPixels,
+ iVerticalUnitInPixels );
+ }
+
+ TInt nextPhase;
+
+ switch ( iLayoutPhase )
+ {
+ case XnLayoutPhase::EMeasure:
+ nextPhase = XnLayoutPhase::ELayout;
+ break;
+ case XnLayoutPhase::ELayout:
+ // Layout is now calculated
+ iCurrentView->SetLaidOutL();
+ iLayoutControl &= ~XnLayoutControl::EViewDirty;
+ // Check nodes which dimensions are changed
+ for ( TInt i = 0; i < laidOutList.Count(); i++ )
+ {
+ CXnNode* node( laidOutList[i] );
+ if( IsSrollableBox( *node ) && node->ScrollableControl() )
+ {
+ node->ScrollableControl()->LayoutChangedL();
+ }
+ if ( /*IsNodeTooltip( *node ) ||*/ !node->IsLaidOut() )
+ {
+ continue;
+ }
+ CXnControlAdapter* adapter( node->Control() );
+ if ( adapter )
+ {
+ TRect rect;
+
+ if ( node->ViewNodeImpl() )
+ {
+ rect = ClientRect();
+
+ // Move it to 0, 0
+ rect.Move( -rect.iTl.iX, -rect.iTl.iY );
+ }
+ else
+ {
+ rect = node->BorderRect();
+ }
+ if ( adapter->Rect() != rect )
+ {
+ AddToRedrawListL( node, rect );
+
+ adapter->SetRect( rect );
+ CXnProperty* prop = node->GetPropertyL(
+ XnPropertyNames::common::KSizeAware );
+ if ( prop && prop->StringValue() ==
+ XnPropertyNames::KTrue )
+ {
+ CXnNode* sizeChanged =
+ BuildTriggerNodeLC( *iUiEngine,
+ XnPropertyNames::action::trigger::name::
+ KSizeChanged );
+ node->ReportXuikonEventL( *sizeChanged );
+ CleanupStack::PopAndDestroy( sizeChanged );
+ }
+ }
+ }
+ }
+ /* flow through */
+ default:
+ nextPhase = XnLayoutPhase::ENone;
+ break;
+ }
+ CleanupStack::PopAndDestroy( &laidOutList );
+ return nextPhase;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::RenderUIL()
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::RenderUIL( CXnNode* /*aNode*/ )
+ {
+ if ( IsLayoutDisabled() )
+ {
+ // Layout is not up-to-date
+ iLayoutControl |= XnLayoutControl::ERenderUI;
+ return;
+ }
+
+#ifdef _XN3_DEBUG_
+ TraceTreeL(iCurrentView );
+#endif
+
+ for( TInt i=0; i<iRedrawRegions.Count(); i++)
+ {
+ CCoeControl* control = iRedrawRegions[i]->iControl;
+ RRegion& redrawRegion = iRedrawRegions[i]->iRegion;
+
+ if( redrawRegion.CheckError() )
+ {
+ // Mark tree rendered
+ iCurrentView->SetRenderedL();
+ // Error occured during dirty set, redraw whole window
+ control->DrawNow();
+ }
+ else
+ {
+ if( !redrawRegion.IsEmpty() )
+ {
+ // Mark tree rendered
+ iCurrentView->SetRenderedL();
+ TInt count( redrawRegion.Count() );
+
+ if( count > 2 )
+ {
+ // Make bounding rect over the dirty areas
+ TRect boundingRect( redrawRegion.BoundingRect() );
+
+ control->DrawNow( boundingRect );
+ }
+ else
+ {
+ for( TInt i = 0; i < count; i++ )
+ {
+ // Draw every dirty area separately
+ TRect redrawRect( redrawRegion[i] );
+
+ control->DrawNow( redrawRect );
+ }
+ }
+ }
+ }
+ redrawRegion.Clear();
+ }
+
+ RefreshMenuL();
+
+ if ( iLayoutControl & XnLayoutControl::EFirstPassDraw )
+ {
+ iViewManager.SetFirstPassDrawCompleteL();
+ iLayoutControl &= ~XnLayoutControl::EFirstPassDraw;
+ }
+
+ iLayoutControl &= ~XnLayoutControl::ERenderUI;
+
+ iAppUiAdapter.EffectManager()->UiRendered();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::RootNode()
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::RootNode()
+ {
+ return iViewManager.RootNode();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ODT()
+// -----------------------------------------------------------------------------
+//
+CXnODT* CXnUiEngineImpl::ODT()
+ {
+ return iViewManager.ODT();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::FindNodeByIdL()
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::FindNodeByIdL( const TDesC& aAreaId,
+ const TDesC& aNamespace )
+ {
+ HBufC8* id = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aAreaId );
+ CleanupStack::PushL( id );
+
+ HBufC8* ns = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aNamespace );
+ CleanupStack::PushL( ns );
+
+ CXnNode* returnValue( FindNodeByIdL( *id, *ns ) );
+
+ CleanupStack::PopAndDestroy( ns );
+ CleanupStack::PopAndDestroy( id );
+
+ return returnValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::FindNodeByIdL()
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::FindNodeByIdL( const TDesC8& aAreaId,
+ const TDesC8& aNamespace )
+ {
+ // Find the namespace where to start node id look-up
+ CXnPluginData* pluginData(
+ iViewManager.ActiveViewData().Plugin( aNamespace ) );
+
+ if ( !pluginData )
+ {
+ return NULL;
+ }
+
+ CXnNode* root( pluginData->Node()->LayoutNode() );
+
+ return ::FindNodeByIdL( root, aAreaId, aNamespace );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::FindNodeByClassL()
+// -----------------------------------------------------------------------------
+//
+CXnPointerArray* CXnUiEngineImpl::FindNodeByClassL(
+ const TDesC& aClassId, const TDesC& aNamespace )
+ {
+ HBufC8* classId = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aClassId );
+ CleanupStack::PushL( classId );
+
+ HBufC8* ns = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aNamespace );
+ CleanupStack::PushL( ns );
+
+ CXnPointerArray* returnValue( FindNodeByClassL( *classId, *ns ) );
+
+ CleanupStack::PopAndDestroy( ns );
+ CleanupStack::PopAndDestroy( classId );
+
+ return returnValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::FindNodeByClassL()
+// -----------------------------------------------------------------------------
+//
+CXnPointerArray* CXnUiEngineImpl::FindNodeByClassL(
+ const TDesC8& aClassId, const TDesC8& aNamespace )
+ {
+ // Find the namespace where to start node class look-up
+ CXnPluginData* pluginData(
+ iViewManager.ActiveViewData().Plugin( aNamespace ) );
+
+ CXnPointerArray* array = CXnPointerArray::NewL();
+ CleanupStack::PushL( array );
+
+ if ( pluginData )
+ {
+ CXnNode* root( pluginData->Node()->LayoutNode() );
+ ::FindNodeByClassL( root, aClassId, *array, aNamespace );
+ }
+
+ CleanupStack::Pop( array );
+
+ return array;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::Resources()
+// -----------------------------------------------------------------------------
+//
+CArrayPtrSeg< CXnResource >& CXnUiEngineImpl::Resources()
+ {
+ return iViewManager.Resources();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::SetFocusedNodeL()
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::SetFocusedNodeL( CXnNode* aFocusedNode, TInt aSource )
+ {
+ iKeyEventDispatcher->SetNodeL( aFocusedNode, aSource );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngine::FocusedNode
+// Forwards the call to the ui engine implementation
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::FocusedNode()
+ {
+ return iKeyEventDispatcher->FocusedNode();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::IsEditMode
+// Returns ETrue if the current mode is edit, otherwise EFalse.
+// -----------------------------------------------------------------------------
+//
+TBool CXnUiEngineImpl::IsEditMode()
+ {
+ return ( iEditMode->EditState() != CXnEditMode::ENone );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::NotifyViewActivatedL()
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::NotifyViewActivatedL( const CXnViewData& /*aViewData*/ )
+ {
+ iCurrentView = iViewManager.ViewNode();
+
+ iControlAdapterList = &iViewManager.Controls();
+ iCurrentViewControlAdapter = iCurrentView->Control();
+
+ iLayoutControl |= XnLayoutControl::EFirstPassDraw;
+
+ iDirtyList.Reset();
+
+ iRedrawRegions.ResetAndDestroy();
+
+ // Set status pane layout
+ CXnProperty* prop( iCurrentView->GetPropertyL(
+ XnPropertyNames::view::KStatusPaneLayout ) );
+
+ // Is there status pane declaration available
+ TInt spane( DetermineStatusPaneLayout( prop ) );
+
+ if ( spane != KErrNotFound )
+ {
+ CEikStatusPane* sp( iAppUiAdapter.StatusPane() );
+
+ if ( sp && sp->CurrentLayoutResId() != spane )
+ {
+ sp->SwitchLayoutL( spane );
+ sp->ApplyCurrentSettingsL();
+ }
+ }
+
+ // Remove previous menubar and stylus popup node
+ iMenuNode = NULL;
+ iStylusPopupNode = NULL;
+
+ iKeyEventDispatcher->ResetMenuNodeL();
+
+ RPointerArray< CXnNode >& children( iCurrentView->Children() );
+
+ for ( TInt count = children.Count() - 1; count >= 0 ; --count )
+ {
+ CXnNode* node( children[count] );
+
+ // Check that the given type of a control is parent
+ // (or ancestor) of this control
+ const TDesC8& type( node->Type()->Type() );
+
+ if ( type == KXnMenuBar )
+ {
+ iMenuNode = node;
+ XnMenuInterface::MXnMenuInterface* menuIf( NULL );
+ XnComponentInterface::MakeInterfaceL( menuIf, node->AppIfL() );
+ if ( menuIf )
+ {
+ menuIf->SetObserver( *this );
+ }
+ }
+ else if ( type == _L8("styluspopup") )
+ {
+ iStylusPopupNode = node;
+
+ static_cast< CXnPopupControlAdapter* >
+ ( node->Control() )->SetObserver( *this );
+ }
+ }
+
+ // Set menu node even if its NULL, to allow keyevent dispatcher
+ // to handle no softkeys
+ iKeyEventDispatcher->SetMenuNodeL( iMenuNode );
+
+ ReportScreenDeviceChangeL();
+
+ SetClientRectL( iAppUiAdapter.ClientRect(), EFalse );
+
+ RootNode()->SetDirtyL();
+ iUiEngine->RenderUIL();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::NotifyWidgetAdditionL()
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::NotifyWidgetAdditionL(
+ const CXnPluginData& /*aPluginData*/ )
+ {
+ iLayoutControl |= XnLayoutControl::EFirstPassDraw;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::DynInitMenuItemL()
+// -----------------------------------------------------------------------------
+//
+TBool CXnUiEngineImpl::DynInitMenuItemL( CXnNodeAppIf& aMenuItem,
+ CXnNodeAppIf* aPlugin )
+ {
+ // dynamic menuitem types reserved for HS internal use,
+ // internal menuitems' origin must be in active view namespace
+ _LIT( KAddWidget, "hs_add_widget" );
+ _LIT( KRemoveWidget, "hs_remove_widget" );
+ _LIT( KAddView, "hs_add_view" );
+ _LIT( KRemoveView, "hs_remove_view" );
+ _LIT( KOnline, "hs_online" );
+ _LIT( KOffline, "hs_offline" );
+
+ CXnProperty* prop(
+ aMenuItem.GetPropertyL( XnPropertyNames::menu::KItemType ) );
+
+ TBool retval( EFalse );
+
+ if( !prop )
+ {
+ // No type defined, declaration error
+ return retval;
+ }
+
+ CXnViewData& viewData( iViewManager.ActiveViewData() );
+
+ TInt viewAmount( iViewManager.ViewAmount() );
+
+ // Check if the menuitem is in view namespace
+ TBool internal( aMenuItem.Namespace() == ActiveView()->Namespace() );
+
+ HBufC* itemType( prop->StringValueL() );
+ CleanupStack::PushL( itemType );
+
+ if ( internal )
+ {
+ if ( *itemType == KAddWidget )
+ {
+ if ( aPlugin )
+ {
+ CXnPluginData& data( viewData.Plugin( &aPlugin->Node() ) );
+
+ if ( !data.Occupied() )
+ {
+ retval = ETrue;
+ }
+ }
+ }
+ else if ( *itemType == KRemoveWidget )
+ {
+ CXnNode* node( ( aPlugin ) ? &aPlugin->Node() : FocusedNode() );
+
+ if ( node )
+ {
+ CXnPluginData& data( viewData.Plugin( node ) );
+
+ if ( data.Removable() && data.Occupied() )
+ {
+ retval = ETrue;
+ }
+ }
+ }
+ else if ( *itemType == KAddView )
+ {
+ // checks Max pages value - from RootData
+ if ( viewAmount < iViewManager.MaxPages() )
+ {
+ retval = ETrue;
+ }
+ }
+ else if ( *itemType == KRemoveView )
+ {
+ if ( viewData.Removable() && viewAmount > 1 )
+ {
+ retval = ETrue;
+ }
+ }
+ else if ( *itemType == KOnline || *itemType == KOffline )
+ {
+ retval = iAppUiAdapter.DynInitMenuItemL( *itemType );
+ }
+ }
+ else
+ {
+ const TDesC8& ns( aMenuItem.Namespace() );
+
+ CXnPluginData* data( viewData.Plugin( ns ) );
+
+ if ( data )
+ {
+ RPointerArray< CXnNode > nodes;
+ CleanupClosePushL( nodes );
+
+ data->ContentSourceNodesL( nodes );
+
+ RPointerArray< CXnNodeAppIf > list;
+ CleanupClosePushL( list );
+
+ for ( TInt i = 0; i < nodes.Count(); i++ )
+ {
+ list.AppendL( &nodes[i]->AppIfL() );
+ }
+
+ retval = iAppUiAdapter.DynInitMenuItemL( *itemType, &list );
+
+ CleanupStack::PopAndDestroy( 2, &nodes ); // list
+ }
+ }
+
+ CleanupStack::PopAndDestroy( itemType );
+
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::VerticalPixelValueL()
+// -----------------------------------------------------------------------------
+//
+TInt CXnUiEngineImpl::VerticalPixelValueL(
+ CXnProperty* aValue, TInt aReferenceValue )
+ {
+ return ::VerticalPixelValueL( aValue, aReferenceValue,
+ *iCurrentGraphicsDevice, iVerticalUnitInPixels );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::HorizontalPixelValueL()
+// -----------------------------------------------------------------------------
+//
+TInt CXnUiEngineImpl::HorizontalPixelValueL(
+ CXnProperty* aValue, TInt aReferenceValue )
+ {
+ return ::HorizontalPixelValueL( aValue, aReferenceValue,
+ *iCurrentGraphicsDevice, iHorizontalUnitInPixels );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::VerticalTwipValueL()
+// -----------------------------------------------------------------------------
+//
+TInt CXnUiEngineImpl::VerticalTwipValueL( CXnProperty* aValue,
+ TInt aReferenceValue )
+ {
+ return iCurrentGraphicsDevice->VerticalPixelsToTwips(
+ VerticalPixelValueL( aValue, aReferenceValue ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::HorizontalTwipValueL()
+// -----------------------------------------------------------------------------
+//
+TInt CXnUiEngineImpl::HorizontalTwipValueL( CXnProperty* aValue,
+ TInt aReferenceValue )
+ {
+ return iCurrentGraphicsDevice->HorizontalPixelsToTwips(
+ HorizontalPixelValueL( aValue, aReferenceValue ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ViewManager()
+// -----------------------------------------------------------------------------
+//
+CXnViewManager* CXnUiEngineImpl::ViewManager()
+ {
+ return &iViewManager;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ActiveView()
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::ActiveView()
+ {
+ return iViewManager.ViewNode();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::RefreshMenuL
+// Refresh current menu
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::RefreshMenuL()
+ {
+ if ( iLayoutControl & XnLayoutControl::ERefreshMenu )
+ {
+ iKeyEventDispatcher->RefreshMenuL();
+ iLayoutControl &= ~XnLayoutControl::ERefreshMenu;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::AddDirtyNodeL
+// Add a dirty node. This method must be called via CXnNode SetDirtyL
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::AddDirtyNodeL( CXnNode* aNode, TInt aLevel )
+ {
+ CXnViewData& data( iViewManager.ActiveViewData() );
+
+ if ( !aNode || ( aNode != RootNode() && !data.Plugin( aNode->Namespace() ) ) )
+ {
+ // No node, or node doesn't belong to active view namespace
+ return;
+ }
+
+ if ( aNode->Type()->Type() == KMenuBar )
+ {
+ iLayoutControl |= XnLayoutControl::ERefreshMenu;
+ return;
+ }
+
+ if ( iLayoutControl & XnLayoutControl::EViewDirty )
+ {
+ // nothing to do
+ return;
+ }
+
+ if ( aLevel == XnDirtyLevel::ERender )
+ {
+ if( aNode == RootNode() )
+ {
+ TXnDirtyRegion* dirtyRegion = FindDirtyRegionL( *iCurrentView );
+ if( dirtyRegion )
+ {
+ dirtyRegion->iRegion.Clear();
+ }
+ aNode = iCurrentView;
+ }
+
+ // Add to redraw list
+ AddToRedrawListL( aNode );
+ }
+ else
+ {
+ // Add to dirty list for relayout and redraw
+ AddToDirtyListL( aNode );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ScreenDeviceSize
+// Get the size of the current screen device
+// -----------------------------------------------------------------------------
+//
+TSize CXnUiEngineImpl::ScreenDeviceSize() const
+ {
+ if ( iCurrentGraphicsDevice )
+ {
+ return iCurrentGraphicsDevice->SizeInPixels();
+ }
+
+ return TSize( 0, 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::IsDialogDisplaying
+// Whether the dialog is displaying or not.
+// -----------------------------------------------------------------------------
+//
+TBool CXnUiEngineImpl::IsDialogDisplaying()
+ {
+ return iAppUiAdapter.IsDisplayingControlBetweenPriorities(
+ ECoeStackPriorityDialog - 1, KXnStackPriorityKeyEventDispatcher - 1 );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::HandleResourceChangeL
+// Handles a change to the control's resources of type aType
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::HandleResourceChangeL( TInt aType )
+ {
+ if ( iMenuNode )
+ {
+ CXnControlAdapter* adapter( iMenuNode->Control() );
+
+ if ( adapter )
+ {
+ adapter->HandleResourceChange( aType );
+ }
+ }
+
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ // Must return here if there is no current view or
+ // controladapterlist. This may occur when the phone
+ // is booted for the first time and the location/date
+ // query is visible.
+ if ( !ActiveView() )
+ {
+ return;
+ }
+
+ // Update client rect
+ SetClientRectL( iAppUiAdapter.ClientRect(), EFalse );
+
+ iEditMode->HandleScreenDeviceChangedL();
+
+ // Force relayout
+ DisableRenderUiLC();
+
+ RootNode()->SetDirtyL();
+
+ ReportScreenDeviceChangeL();
+
+ for ( TInt i = 0; i < iControlAdapterList->Count(); i++ )
+ {
+ CXnControlAdapter* adapter( ( *iControlAdapterList )[i] );
+
+ adapter->HandleScreenDeviceChangedL();
+ }
+
+ ForceRenderUIL();
+
+ CleanupStack::PopAndDestroy();
+ }
+ else if ( aType == KAknsMessageSkinChange )
+ {
+ // Force relayout
+ DisableRenderUiLC();
+
+ RootNode()->SetDirtyL();
+
+ for ( TInt i = 0; i < iControlAdapterList->Count(); i++ )
+ {
+ CXnControlAdapter* adapter( ( *iControlAdapterList )[i] );
+ adapter->SkinChanged();
+ }
+
+ ForceRenderUIL();
+
+ CleanupStack::PopAndDestroy();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::IsMenuDisplaying
+// Checks whether the menu is displaying or not.
+// -----------------------------------------------------------------------------
+//
+TBool CXnUiEngineImpl::IsMenuDisplaying()
+ {
+ return iKeyEventDispatcher->IsMenuFocused();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::MenubarNode
+// Returns menubar node
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::MenuBarNode() const
+ {
+ return iMenuNode;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::StylusPopupNode
+// Returns stylus popup node
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::StylusPopupNode() const
+ {
+ return iStylusPopupNode;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::AddPassiveFocusedNode
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::AddPassiveFocusedNodeL( CXnNode* aNode )
+ {
+ iKeyEventDispatcher->AddPassiveFocusedNodeL( aNode );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::RemovePassiveFocusedNode
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::RemovePassiveFocusedNodeL( CXnNode* aNode )
+ {
+ iKeyEventDispatcher->RemovePassiveFocusedNodeL( aNode );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::AddPassiveFocusedNode
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::ClearPassiveFocusedNodesL()
+ {
+ iKeyEventDispatcher->ClearPassiveFocusedNodesL();
+ }
+
+// -----------------------------------------------------------------------------
+// SetNodeDroppedL()
+// Sets node's dropped state
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::SetNodeDroppedL( CXnNode& aNode, TInt aDropped ) const
+ {
+ if ( aDropped != XnNodeLayout::ENone )
+ {
+ CXnNode* parent( aNode.Parent() );
+ TInt parentAdaptive( parent->IsAdaptive( ETrue ) );
+
+ if ( iLayoutPhase == XnLayoutPhase::EMeasure )
+ {
+ if ( !parentAdaptive )
+ {
+ // Only adaptive childs can be dropped during measure phase
+ return;
+ }
+ }
+
+#ifdef _XN3_DEBUG_
+ CXnProperty* id( aNode.IdL() );
+
+ if ( id )
+ {
+ TBuf8< 256 > debug;
+ debug.Append( _L8( "Node id: " ) );
+ debug.Append( id->StringValue() );
+ debug.Append( _L8( " will be set to dropped" ) );
+ RDebug::RawPrint( debug );
+ }
+#endif
+
+ // Node will be dropped
+ aNode.SetDropped( aDropped );
+
+ // Get ride of its rects
+ ClearRects( aNode );
+
+ if ( parentAdaptive )
+ {
+ // Is there adaptive content left after dropping?
+ CheckAdaptiveContentL( *parent, parent->Rect().Size() );
+ }
+ }
+ else
+ {
+ // Node is no more dropped
+ aNode.SetDropped( aDropped );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CheckAdaptiveContentL()
+// Checks if node is adaptive, but doesn't have any content
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::CheckAdaptiveContentL(
+ CXnNode& aNode, TSize aAvailableSize ) const
+ {
+ TInt adaptive( aNode.IsAdaptive( ETrue ) );
+ TBool isEmpty( EFalse );
+
+ if ( adaptive )
+ {
+ if ( aAvailableSize == TSize::EUninitialized )
+ {
+ // Use max available size
+ aAvailableSize = ScreenDeviceSize();
+ }
+
+ const TDesC8& name( aNode.Type()->Type() );
+
+ if ( name == KBoxNodeName || name == KButtonNodeName )
+ {
+ RPointerArray< CXnNode > displayedChildren;
+ CleanupClosePushL( displayedChildren );
+
+ TInt displayedCount( DisplayedChildrenCountL(
+ aNode, &displayedChildren ) );
+
+ if ( displayedCount == 0 )
+ {
+ isEmpty = ETrue;
+ }
+ else
+ {
+ for ( TInt i = 0; i < displayedChildren.Count(); i++ )
+ {
+ CheckAdaptiveContentL( *displayedChildren[i],
+ aAvailableSize );
+ }
+
+ if ( DisplayedChildrenCountL( aNode ) == 0 )
+ {
+ isEmpty = ETrue;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &displayedChildren );
+ }
+
+ if ( isEmpty )
+ {
+ // No content available, drop adaptive node
+ SetNodeDroppedL( aNode, XnNodeLayout::EDropped );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::AddFocusCandidateL
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::AddFocusCandidateL( CXnNode* aNode )
+ {
+ if ( !aNode )
+ {
+ return;
+ }
+ TInt index( iFocusCandidateList.Find( aNode ) );
+ if ( index == KErrNotFound )
+ {
+ iFocusCandidateList.AppendL( aNode );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::IsLayoutDisabled
+// -----------------------------------------------------------------------------
+//
+TBool CXnUiEngineImpl::IsLayoutDisabled()
+ {
+ if ( !iCurrentView )
+ {
+ return ETrue;
+ }
+
+ TBool retval( EFalse );
+ if ( iDisableCount > 0 &&
+ !( iLayoutControl & XnLayoutControl::EIgnoreState ) )
+ {
+ retval = ETrue;
+ }
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// AddToRedrawListL
+// Mark Control's appearance to be redrawn
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::AddToRedrawListL( CXnNode* aNode, TRect aRect )
+ {
+ CXnControlAdapter* aAdapter( aNode->Control() );
+
+ if( !aAdapter )
+ {
+ return;
+ }
+
+ if( aRect != TRect::EUninitialized )
+ {
+ // This is the new rect which will be set by layout algo
+ AddRedrawRectL( aRect, *aNode );
+ }
+
+ TRect rect( aAdapter->Rect() );
+
+ if( rect == TRect::EUninitialized )
+ {
+ // Don't add uninitialized rect
+ return;
+ }
+
+ /*
+ if( aNode->IsStateSet( XnPropertyNames::style::common::KFocus ) )
+ {
+ const TDesC8& name( aNode->DomNode()->Name() );
+
+ if( name == KPlugin )
+ {
+ rect.Grow( KFocusGrowValue, KFocusGrowValue );
+ }
+ else
+ {
+ TRect marginRect( aNode->MarginRect() );
+
+ CXnNode* parent( aNode->Parent() );
+
+ for( ; parent; parent = parent->Parent() )
+ {
+ if( parent->DomNode()->Name() == KPlugin )
+ {
+ if( parent->Rect() == marginRect )
+ {
+ rect.Grow( KFocusGrowValue, KFocusGrowValue );
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ */
+ GrowIfNeeded(aNode, rect);
+ AddRedrawRectL( rect, *aNode );
+ }
+
+// -----------------------------------------------------------------------------
+// AddToDirtyListL
+// Mark node to dirty list for relayout
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::AddToDirtyListL( CXnNode* aNode )
+ {
+ CXnNode* nodeToRedrawList( aNode );
+ CXnNode* nodeToDirtyList( aNode );
+
+ if ( aNode == RootNode() )
+ {
+ // Force relayout and redraw from current view
+ iDirtyList.Reset();
+ iDirtyList.AppendL( iCurrentView );
+ TXnDirtyRegion* dirtyRegion = FindDirtyRegionL( *iCurrentView );
+ if( dirtyRegion )
+ {
+ dirtyRegion->iRegion.Clear();
+ }
+ iLayoutControl |= XnLayoutControl::EViewDirty;
+ nodeToDirtyList = nodeToRedrawList = iCurrentView;
+ nodeToDirtyList->ClearRenderedAndLaidOut();
+
+ // Add to draw list for redraw
+ AddToRedrawListL( nodeToRedrawList );
+ }
+ else
+ {
+ if ( !IsAbsoluteL( *aNode ) && !IsNodeTooltip( *aNode ) )
+ {
+ // Check adaptives in normal flow
+ CXnNode* oldest( NULL );
+ CXnNode* adaptive( aNode );
+
+ if ( !aNode->IsAdaptive( ETrue ) )
+ {
+ adaptive = aNode->Parent();
+ }
+
+ for ( ; adaptive && adaptive->IsAdaptive( ETrue );
+ adaptive = adaptive->Parent() )
+ {
+ oldest = adaptive;
+ }
+
+ // Now we have found the oldest adaptive node if present
+ if ( oldest )
+ {
+ nodeToRedrawList = nodeToDirtyList = adaptive;
+ }
+ }
+
+ RPointerArray< CXnNode > dirtyList;
+ CleanupClosePushL( dirtyList );
+ TInt count( iDirtyList.Count() );
+ TBool found;
+
+ // first, check that aNode's children are not in the dirty array
+ for ( TInt i = 0; i < count; ++i )
+ {
+ found = EFalse;
+ CXnNode* candidate( iDirtyList[i] );
+
+ for ( CXnNode* node = candidate->Parent(); node && !found;
+ node = node->Parent() )
+ {
+ if ( nodeToDirtyList == node )
+ {
+ found = ETrue;
+ }
+ }
+
+ if ( !found )
+ {
+ // Put candidate back to list as child is not found
+ dirtyList.AppendL( candidate );
+ }
+ }
+
+ found = EFalse;
+
+ // second, check that aNode's parent is not in dirty array
+ for ( TInt i = 0; i < count && !found; ++i )
+ {
+ CXnNode* candidate( iDirtyList[i] );
+
+ for ( CXnNode* node = nodeToDirtyList; node && !found;
+ node = node->Parent() )
+ {
+ if ( node == candidate )
+ {
+ found = ETrue;
+ }
+ }
+ }
+
+ if ( !found && iDirtyList.Find( nodeToDirtyList ) == KErrNotFound )
+ {
+ // Add node to dirty list as parent is neither found
+ dirtyList.AppendL( nodeToDirtyList );
+ nodeToDirtyList->ClearRenderedAndLaidOut();
+
+ // Add to draw list for redraw
+ AddToRedrawListL( nodeToRedrawList );
+ }
+
+ // finally update the dirty list
+ iDirtyList.Reset();
+ iDirtyList = dirtyList;
+
+ CleanupStack::Pop( &dirtyList );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::SetClientRectL
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::SetClientRectL( TRect aRect, TBool aDrawNow )
+ {
+ if ( iClientRect != aRect )
+ {
+ iClientRect = aRect;
+
+ UpdateInternalUnits( iHorizontalUnitInPixels, iVerticalUnitInPixels,
+ iClientRect );
+
+ iAppUiAdapter.ViewAdapter().BgControl().SetRect( aRect );
+
+ if ( aDrawNow )
+ {
+ RootNode()->SetDirtyL();
+ iUiEngine->RenderUIL();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ClientRect
+// -----------------------------------------------------------------------------
+//
+TRect CXnUiEngineImpl::ClientRect() const
+ {
+ return iClientRect;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::Editor
+// -----------------------------------------------------------------------------
+//
+CXnEditor* CXnUiEngineImpl::Editor()const
+ {
+ return &iViewManager.Editor();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::EditMode
+// -----------------------------------------------------------------------------
+//
+CXnEditMode* CXnUiEngineImpl::EditMode()
+ {
+ return iEditMode;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::StartLayoutFromL
+// -----------------------------------------------------------------------------
+//
+CXnNode* CXnUiEngineImpl::StartLayoutFromL()
+ {
+ if ( iLayoutControl & XnLayoutControl::EViewDirty )
+ {
+ return iCurrentView;
+ }
+
+ RPointerArray< CXnNode >parentArray;
+ CleanupClosePushL( parentArray );
+ TInt dirtyCount = iDirtyList.Count();
+ CXnNode* startNode( NULL );
+
+ for ( TInt dirtyIndex = 0; dirtyIndex < dirtyCount; dirtyIndex++ )
+ {
+ startNode = iDirtyList[dirtyIndex];
+
+ for ( ;startNode && startNode != iCurrentView; )
+ {
+ parentArray.Append( startNode->Parent() );
+ startNode = startNode->Parent();
+ }
+ }
+
+ TInt parentCount = parentArray.Count();
+
+ for ( TInt parentIndex = 0; parentIndex < parentCount; parentIndex++ )
+ {
+ TInt parentsFound = 0;
+
+ for ( TInt checkIndex = 0; checkIndex < parentCount; checkIndex++ )
+ {
+ if ( parentArray[parentIndex] == parentArray[checkIndex] )
+ {
+ parentsFound++;
+
+ if ( parentsFound == dirtyCount )
+ {
+ startNode = parentArray[parentIndex];
+ CleanupStack::PopAndDestroy( &parentArray );
+ return startNode;
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &parentArray );
+
+ return iCurrentView;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::Plugins
+// -----------------------------------------------------------------------------
+//
+RPointerArray< CXnNode >* CXnUiEngineImpl::Plugins()
+ {
+ return &iViewManager.PluginNodes();
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::ForceRenderUIL
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::ForceRenderUIL( TBool aLayoutOnly )
+ {
+ iLayoutControl |= XnLayoutControl::EIgnoreState;
+ if ( aLayoutOnly )
+ {
+ LayoutUIL();
+ }
+ else
+ {
+ LayoutUIL();
+ RenderUIL();
+ }
+ iLayoutControl &= ~XnLayoutControl::EIgnoreState;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::HitTest
+// -----------------------------------------------------------------------------
+//
+CXnHitTest& CXnUiEngineImpl::HitTest() const
+ {
+ return *iHitTest;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::PositionStylusPopupL
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::PositionStylusPopupL( CXnNode& aNode,
+ CXnNode& aReference, const TPoint& aPosition )
+ {
+ CXnDomStringPool& sp( aNode.DomNode()->StringPool() );
+ TXnDirtyRegion* dirtyRegion = FindDirtyRegionL( *iCurrentView );
+ RRegion region;
+ region.Copy( dirtyRegion->iRegion );
+ CleanupClosePushL( region );
+
+ // Set initial position to (0, 0) to calculate popup metrics
+ CXnProperty* top = CXnProperty::NewL(
+ XnPropertyNames::style::common::KTop, 0,
+ CXnDomPropertyValue::EPx, sp );
+ CleanupStack::PushL( top );
+ aNode.SetPropertyL( top );
+ CleanupStack::Pop( top );
+ top = NULL;
+ CXnProperty* left = CXnProperty::NewL(
+ XnPropertyNames::style::common::KLeft, 0,
+ CXnDomPropertyValue::EPx, sp );
+ CleanupStack::PushL( left );
+ aNode.SetPropertyL( left );
+ CleanupStack::Pop( left );
+ left = NULL;
+
+ // Make it visible
+ CXnProperty* display = CXnProperty::NewL(
+ XnPropertyNames::style::common::KDisplay,
+ XnPropertyNames::style::common::display::KBlock,
+ CXnDomPropertyValue::EString, sp );
+ CleanupStack::PushL( display );
+ aNode.SetPropertyL( display );
+ CleanupStack::Pop( display );
+
+ if ( !aNode.IsLaidOut() || !aReference.IsLaidOut() )
+ {
+ ForceRenderUIL( ETrue );
+ }
+
+ if ( !aNode.IsLaidOut() || !aReference.IsLaidOut() )
+ {
+ // Something went wrong
+ CleanupStack::PopAndDestroy( ®ion );
+
+ return;
+ }
+
+ TRect rectToFit( aReference.MarginRect() );
+ TRect marginRect( aNode.MarginRect() );
+
+ if ( marginRect.Height() > rectToFit.Height() ||
+ marginRect.Width() > rectToFit.Width() )
+ {
+ // Won't fit even how much is moved
+ CleanupStack::PopAndDestroy( ®ion );
+
+ return;
+ }
+
+ TPoint tl;
+ TPoint br;
+
+ // Remove the initial 0,0 from redraw region and rects
+ dirtyRegion->iRegion.Clear();
+ ClearRects( aNode, ETrue );
+ CXnProperty* positionHint( aNode.GetPropertyL(
+ XnPropertyNames::styluspopup::KPositionHint ) );
+
+ // Default
+ const TDesC8* value( &XnPropertyNames::styluspopup::positionhint::KAbove );
+
+ if ( positionHint )
+ {
+ value = &positionHint->StringValue();
+ }
+
+ if ( *value == XnPropertyNames::styluspopup::positionhint::KAbove )
+ {
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ tl = aPosition;
+ tl.iY -= marginRect.Height();
+ tl.iX -= marginRect.Width();
+
+ // Will the popup float out?
+ if ( !rectToFit.Contains( tl ) )
+ {
+ // top left floated out
+ TInt y( rectToFit.iTl.iY - tl.iY + 1 );
+
+ if ( y >= 0 )
+ {
+ // y-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iY = tl.iY + y;
+ }
+
+ TInt x( rectToFit.iTl.iX - tl.iX + 1 );
+
+ if ( x >= 0 )
+ {
+ // x-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iX = tl.iX + x;
+ }
+ }
+ }
+ else
+ {
+ tl = aPosition;
+ tl.iY -= marginRect.Height();
+
+ // Will the popup float out?
+ if ( !rectToFit.Contains( tl ) )
+ {
+ // top left floated out
+ TInt y( rectToFit.iTl.iY - tl.iY + 1 );
+
+ if ( y >= 0 )
+ {
+ // y-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iY = tl.iY + y;
+ }
+ }
+
+ br = TPoint( tl.iX + marginRect.Width(),
+ tl.iY + marginRect.Height() );
+
+ if ( !rectToFit.Contains( br ) )
+ {
+ // bottom right floated out
+ TInt x( br.iX - rectToFit.iBr.iX + 1 );
+
+ if ( x >= 0 )
+ {
+ // x-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iX = tl.iX - x;
+ }
+ }
+ }
+ }
+ else // value == XnPropertyNames::styluspopup::positionhint::KBelow
+ {
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ tl = aPosition;
+ tl.iX = tl.iX - marginRect.Width();
+
+ if ( !rectToFit.Contains( tl ) )
+ {
+ // Top left floated out
+ TInt x( rectToFit.iTl.iX - tl.iX + 1 );
+
+ if ( x >= 0 )
+ {
+ // x-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iX = tl.iX + x;
+ }
+ }
+
+ br = TPoint( tl.iX + marginRect.Width(),
+ tl.iY + marginRect.Height() );
+
+ if ( !rectToFit.Contains( br ) )
+ {
+ // bottom right floated out
+ TInt y( br.iY - rectToFit.iBr.iY + 1 );
+
+ if ( y >= 0 )
+ {
+ // y-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iY = tl.iY - y;
+ }
+ }
+ }
+ else
+ {
+ tl = aPosition;
+ br = TPoint( tl.iX + marginRect.Width(),
+ tl.iY + marginRect.Height() );
+
+ // Will the popup float out?
+ if ( !rectToFit.Contains( br ) )
+ {
+ // Bottom right floated out
+ TInt x( br.iX - rectToFit.iBr.iX + 1 );
+
+ if ( x >= 0 )
+ {
+ // x-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iX = tl.iX - x;
+ }
+
+ TInt y( br.iY - rectToFit.iBr.iY + 1 );
+
+ if ( y >= 0 )
+ {
+ // y-coordinate floated out, move it position
+ // so that it will be inside reference rect
+ tl.iY = tl.iY - y;
+ }
+ }
+ }
+ }
+
+ // Set positions
+ top = CXnProperty::NewL(
+ XnPropertyNames::style::common::KTop, tl.iY,
+ CXnDomPropertyValue::EPx, sp );
+ CleanupStack::PushL( top );
+ aNode.SetPropertyL( top );
+ CleanupStack::Pop( top );
+ left = CXnProperty::NewL(
+ XnPropertyNames::style::common::KLeft, tl.iX,
+ CXnDomPropertyValue::EPx, sp );
+ CleanupStack::PushL( left );
+ aNode.SetPropertyL( left );
+ CleanupStack::Pop( left );
+
+ // Copy stored region back
+ dirtyRegion->iRegion.Copy( region );
+ CleanupStack::PopAndDestroy( ®ion );
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::GetThemeResource
+// -----------------------------------------------------------------------------
+//
+TInt CXnUiEngineImpl::GetThemeResource( const TDesC& aPath, RFile& aFile )
+ {
+ TInt err = KErrNone;
+
+ // parse file name and extension
+ TParsePtrC fileParser( aPath );
+ TPtrC filepath = fileParser.DriveAndPath();
+
+ RFs session ( CCoeEnv::Static()->FsSession() );
+
+ // open resource file
+ session.SetSessionPath( filepath );
+ session.ShareProtected();
+ err = aFile.Open( session, aPath, EFileShareReadersOnly );
+ if ( err != KErrNone )
+ {
+ aFile.Close();
+ }
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::AnalyseAddedWidgetL
+// -----------------------------------------------------------------------------
+//
+TBool CXnUiEngineImpl::AnalyseAddedWidgetL( CXnNode& aNode )
+ {
+ TBool retval( ETrue );
+
+ // Force layout to analyse added widget's dimensions
+ ForceRenderUIL( ETrue );
+
+ if ( aNode.IsAdaptive( ETrue ) )
+ {
+ // If widget place holder (plugin in view.xml) is adaptive, then
+ // we need to verify that added widget will fit to available space
+ retval = EFalse;
+
+ CXnNode* parent( aNode.Parent() );
+ RPointerArray< CXnNode >& children( parent->Children() );
+ CXnProperty* prop( parent->BlockProgressionL() );
+
+ const TDesC8* bp(
+ &XnPropertyNames::style::common::block_progression::KTB() );
+
+ if ( prop )
+ {
+ bp = &prop->StringValue();
+ }
+
+ prop = parent->DirectionL();
+
+ const TDesC8* dir(
+ &XnPropertyNames::style::common::direction::KLTR() );
+
+ if ( prop )
+ {
+ // use default
+ dir = &prop->StringValue();
+ }
+
+ TSize space( CalculateSpaceUsedByChildrenL( children, *parent,
+ *bp, *dir, *iCurrentGraphicsDevice, iHorizontalUnitInPixels,
+ iVerticalUnitInPixels ) );
+
+ TSize parentSize( parent->Rect().Size() );
+
+ if ( *bp == XnPropertyNames::style::common::block_progression::KTB ||
+ *bp == XnPropertyNames::style::common::block_progression::KBT )
+ {
+ if ( parentSize.iHeight >= space.iHeight )
+ {
+ retval = ETrue;
+ }
+ }
+ else // LR / RL
+ {
+ if ( parentSize.iWidth >= space.iWidth )
+ {
+ retval = ETrue;
+ }
+ }
+ }
+
+ return retval;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::NotifyWidgetRemovalL( )
+// Notify about widget removal
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::NotifyWidgetRemovalL(
+ const CXnPluginData& /*aPluginData*/ )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::NotifyConfigureWidgetL( )
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::NotifyConfigureWidgetL(
+ const CHsContentInfo& /*aContentInfo*/, CXnPluginData& /*aPluginData*/ )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CXnUiEngineImpl::NotifyViewDeactivatedL
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::NotifyViewDeactivatedL(
+ const CXnViewData& /*aViewData*/ )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::DisableRenderUiLC()
+ {
+ CleanupStack::PushL( TCleanupItem( EnableRenderUi, this ) );
+
+ iDisableCount++;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+EXPORT_C /* static */ void CXnUiEngineImpl::EnableRenderUi( TAny* aAny )
+ {
+ CXnUiEngineImpl* self = static_cast< CXnUiEngineImpl* >( aAny );
+
+ if ( self->iDisableCount > 0 )
+ {
+ self->iDisableCount--;
+
+ if ( self->iDisableCount == 0 )
+ {
+ TRAP_IGNORE(
+ // Is menu refresh pending?
+ if ( ( self->iLayoutControl & XnLayoutControl::ERefreshMenu ) &&
+ !self->IsMenuDisplaying() )
+ {
+ // RefreshMenuL will reset the state flag
+ self->RefreshMenuL();
+ }
+
+ // Is layout pending?
+ if ( self->iLayoutControl & XnLayoutControl::ELayoutUI )
+ {
+ self->LayoutUIL();
+ }
+
+ // Is render pending?
+ if ( self->iLayoutControl & XnLayoutControl::ERenderUI )
+ {
+ self->RenderUIL();
+ }
+ );
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CXnUiEngineImpl::ReportScreenDeviceChangeL()
+ {
+ CXnNode* trigger( BuildScreenDeviceChangeTriggerNodeLC( *iUiEngine ) );
+
+ // Notify current orientation to iCurrentView
+ iCurrentView->ReportXuikonEventL( *trigger );
+
+ // Notify also plugins
+ RPointerArray<CXnNode> plugins = *Plugins();
+ for( TInt i=0; i<plugins.Count(); i++ )
+ {
+ CXnNode* pluginNode = plugins[i];
+ RPointerArray<CXnNode> pluginChildren = pluginNode->Children();
+ for( TInt ii=0; ii<pluginChildren.Count(); ii++ )
+ {
+ CXnDomNode* widgetNode = pluginChildren[ii]->DomNode();
+ if( widgetNode && widgetNode->Name() == KWidgetNodeName )
+ {
+ pluginChildren[ii]->ReportXuikonEventL( *trigger );
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // trigger
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+CCoeControl* CXnUiEngineImpl::WindowOwningControl( CXnNode& aNode )
+ {
+ CXnNode* parent = &aNode;
+ while( parent )
+ {
+ CXnControlAdapter* adapter = parent->Control();
+ if( adapter )
+ {
+ if( parent->ViewNodeImpl() &&
+ adapter == iCurrentViewControlAdapter )
+ {
+ return adapter;
+ }
+ else if( adapter->OwnsWindow() )
+ {
+ if( !IsNodeTooltip( *parent ) )
+ {
+ return adapter;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ }
+ parent = parent->Parent();
+ }
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+TXnDirtyRegion* CXnUiEngineImpl::FindDirtyRegionL( CXnNode& aNode )
+ {
+ CCoeControl* control = WindowOwningControl( aNode );
+ if( !control )
+ {
+ return NULL;
+ }
+ for( TInt i=0; i<iRedrawRegions.Count(); i++ )
+ {
+ if( iRedrawRegions[i]->iControl == control )
+ {
+ return iRedrawRegions[i];
+ }
+ }
+ TXnDirtyRegion* region = new (ELeave) TXnDirtyRegion;
+ CleanupStack::PushL( region );
+ region->iControl = control;
+ iRedrawRegions.AppendL( region );
+ CleanupStack::Pop();
+ return region;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+void CXnUiEngineImpl::AddRedrawRectL( TRect aRect, CXnNode& aNode )
+ {
+ TXnDirtyRegion* dirtyReg = FindDirtyRegionL( aNode );
+ if( dirtyReg )
+ {
+ dirtyReg->iRegion.AddRect( aRect );
+ dirtyReg->iRegion.Tidy();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// SetEventDispatcher
+// -----------------------------------------------------------------------------
+void CXnUiEngineImpl::SetEventDispatcher( CXnKeyEventDispatcher* aDispatcher )
+ {
+ iKeyEventDispatcher = aDispatcher;
+ }
+
+// -----------------------------------------------------------------------------
+// NotifyStatusPaneSizeChanged
+// -----------------------------------------------------------------------------
+void CXnUiEngineImpl::NotifyStatusPaneSizeChanged()
+ {
+ TRAP_IGNORE( iUiEngine->SetClientRectL( iAppUiAdapter.ClientRect() ) );
+ }
+
+// -----------------------------------------------------------------------------
+// NotifyResourceChanged
+// -----------------------------------------------------------------------------
+void CXnUiEngineImpl::NotifyResourceChanged( TInt aType )
+ {
+ TRAP_IGNORE( HandleResourceChangeL( aType ) );
+ }
+
+// End of file