webengine/wmlengine/src/lmgr/src/LMgrContainerBox.cpp
changeset 0 dd21522fd290
child 37 cb62a4f66ebe
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2000 - 2004 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "nw_lmgr_containerboxi.h"
       
    20 #include "nw_lmgr_box.h"
       
    21 #include "nw_lmgr_flowbox.h"
       
    22 #include "nw_lmgr_rootbox.h"
       
    23 #include "nw_lmgr_splittextbox.h"
       
    24 #include "nw_lmgr_statictablebox.h"
       
    25 #include "nw_lmgr_statictablerowbox.h"
       
    26 #include "nw_lmgr_statictablecellbox.h"
       
    27 #include "nw_lmgr_activecontainerbox.h"
       
    28 #include "nw_lmgr_cssproperties.h"
       
    29 #include "nw_adt_resizablevector.h"
       
    30 #include "nw_lmgr_eventhandler.h"
       
    31 #include "GDIDeviceContext.h"
       
    32 #include "nw_lmgr_slavepropertylist.h"
       
    33 #include "nw_adt_vectoriterator.h"
       
    34 #include "BrsrStatusCodes.h"
       
    35 #include "BoxRender.h"
       
    36 #include "nwx_logger.h"
       
    37 #include "nwx_settings.h"
       
    38 #include "ObjectUtils.h"
       
    39 #include "nw_lmgr_posflowbox.h"
       
    40 
       
    41 /* ------------------------------------------------------------------------- *
       
    42    private final methods
       
    43  * ------------------------------------------------------------------------- */
       
    44 
       
    45 /* ------------------------------------------------------------------------- *
       
    46    static data
       
    47  * ------------------------------------------------------------------------- */
       
    48 
       
    49 const
       
    50 NW_LMgr_ContainerBox_Class_t  NW_LMgr_ContainerBox_Class = {
       
    51   { /* NW_Object_Core            */
       
    52     /* super                     */ &NW_LMgr_Box_Class,
       
    53     /* queryInterface            */ _NW_Object_Base_QueryInterface
       
    54   },
       
    55   { /* NW_Object_Base            */
       
    56     /* interfaceList             */ NULL
       
    57   },
       
    58   { /* NW_Object_Dynamic         */
       
    59     /* instanceSize              */ sizeof (NW_LMgr_ContainerBox_t),
       
    60     /* construct                 */ _NW_LMgr_ContainerBox_Construct,
       
    61     /* destruct                  */ _NW_LMgr_ContainerBox_Destruct
       
    62   },
       
    63   { /* NW_LMgr_Box               */
       
    64     /* split                     */ _NW_LMgr_Box_Split,
       
    65     /* resize                    */ _NW_LMgr_ContainerBox_Resize,
       
    66     /* postResize                */ _NW_LMgr_Box_PostResize,
       
    67     /* getMinimumContentSize     */ _NW_LMgr_Box_GetMinimumContentSize,
       
    68     /* hasFixedContentSize       */ _NW_LMgr_Box_HasFixedContentSize,
       
    69     /* constrain                 */ _NW_LMgr_Box_Constrain,
       
    70     /* draw                      */ _NW_LMgr_Box_Draw,
       
    71     /* render                    */ _NW_LMgr_ContainerBox_Render,
       
    72     /* getBaseline               */ _NW_LMgr_ContainerBox_GetBaseline,
       
    73     /* shift                     */ _NW_LMgr_ContainerBox_Shift,
       
    74     /* clone                     */ _NW_LMgr_ContainerBox_Clone
       
    75   },
       
    76   { /* NW_LMgr_ContainerBox      */
       
    77     /* unused                    */ NW_Object_Unused
       
    78   }
       
    79 };
       
    80 
       
    81 /* ------------------------------------------------------------------------- *
       
    82    virtual methods
       
    83  * ------------------------------------------------------------------------- */
       
    84 
       
    85 /* ------------------------------------------------------------------------- *
       
    86  * Function:     NW_LMgr_ContainerBox_Construct
       
    87  * Description:  The constructor.
       
    88  * Returns:      KBrsrSuccess, KBrsrOutOfMemory.
       
    89  */
       
    90 
       
    91 TBrowserStatusCode
       
    92 _NW_LMgr_ContainerBox_Construct (NW_Object_Dynamic_t* dynamicObject,
       
    93                                  va_list* argp)
       
    94 {
       
    95   NW_LMgr_ContainerBox_t* container;
       
    96 
       
    97   NW_TRY(status) {
       
    98   
       
    99     /* for convenience */
       
   100     container = NW_LMgr_ContainerBoxOf (dynamicObject);
       
   101   
       
   102     /* invoke our superclass constructor */
       
   103     status = _NW_LMgr_Box_Construct (dynamicObject, argp);
       
   104     _NW_THROW_ON_ERROR(status);
       
   105   
       
   106     /* initialize the member variables */
       
   107     container->children = (NW_ADT_DynamicVector_t*)
       
   108       NW_ADT_ResizableVector_New (sizeof (NW_LMgr_Box_t*), 0, 5 );
       
   109     NW_THROW_OOM_ON_NULL(container->children, status);
       
   110   }
       
   111   NW_CATCH(status) {
       
   112   }
       
   113   NW_FINALLY {
       
   114     return status;
       
   115   }
       
   116   NW_END_TRY
       
   117 }
       
   118 
       
   119 /* ------------------------------------------------------------------------- *
       
   120  * Function:     NW_LMgr_ContainerBox_Destruct
       
   121  * Description:  The destructor.
       
   122  * Returns:      void
       
   123  */
       
   124 
       
   125 void
       
   126 _NW_LMgr_ContainerBox_Destruct (NW_Object_Dynamic_t* dynamicObject)
       
   127 {
       
   128   NW_LMgr_ContainerBox_t* container;
       
   129   NW_ADT_Vector_Metric_t numChildren;
       
   130   NW_Int32 index;
       
   131   
       
   132   /* for convenience */
       
   133   container = NW_LMgr_ContainerBoxOf (dynamicObject);
       
   134   
       
   135   if (container->children != NULL) {
       
   136     /* before deleting the object, we must delete any children
       
   137        contained by us */
       
   138     numChildren =
       
   139       NW_ADT_Vector_GetSize (container->children);
       
   140     for (index = numChildren - 1; index >= 0; index--) {
       
   141       NW_LMgr_Box_t* child;
       
   142     
       
   143       child = *(NW_LMgr_Box_t**)
       
   144         NW_ADT_Vector_ElementAt (container->children,
       
   145                                  (NW_ADT_Vector_Metric_t) index);
       
   146       NW_Object_Delete (child);
       
   147     }
       
   148   
       
   149     /* release our resources */
       
   150     NW_Object_Delete (container->children);
       
   151   } 
       
   152 }
       
   153 
       
   154 
       
   155 TBrowserStatusCode
       
   156 _NW_LMgr_ContainerBox_Resize( NW_LMgr_Box_t* box, NW_LMgr_FormatContext_t* context )
       
   157 {
       
   158   TBrowserStatusCode status;
       
   159   NW_LMgr_ContainerBox_t* container; 
       
   160 
       
   161   NW_REQUIRED_PARAM( context );
       
   162   NW_ASSERT( box != NULL );
       
   163 
       
   164   container = NW_LMgr_ContainerBoxOf( box );
       
   165   status = NW_LMgr_ContainerBox_ResizeToChildren( container );
       
   166   if (NW_Object_IsInstanceOf(NW_LMgr_BoxOf(NW_LMgr_Box_GetParent(box)),& NW_LMgr_PosFlowBox_Class))
       
   167       {
       
   168       NW_GDI_Dimension2D_t size;
       
   169       NW_LMgr_Box_GetSizeProperties(box, &size);
       
   170       if (size.width > box->iFormatBounds.dimension.width)
       
   171           {
       
   172           box->iFormatBounds.dimension.width = size.width;
       
   173           }
       
   174 
       
   175       if (size.height > box->iFormatBounds.dimension.height)
       
   176           {
       
   177           box->iFormatBounds.dimension.height = size.height;
       
   178           }
       
   179       }
       
   180   return status; 
       
   181 }
       
   182 
       
   183 /* ------------------------------------------------------------------------- *
       
   184  * Function:     NW_LMgr_ContainerBox_Shift
       
   185  * Description:  ContainerBox::Shift shifts the container and the subtree
       
   186  *               below it.
       
   187  * Returns:      KBrsrSuccess, KBrsrOutOfMemory.
       
   188  */
       
   189 
       
   190 TBrowserStatusCode
       
   191 _NW_LMgr_ContainerBox_Shift (NW_LMgr_Box_t* box, 
       
   192                              NW_GDI_Point2D_t *delta)
       
   193 {
       
   194   NW_LMgr_BoxVisitor_t * visitor = NULL;
       
   195   NW_LMgr_Box_t *child;
       
   196 
       
   197   NW_TRY(status) {
       
   198 
       
   199     NW_ASSERT(box != NULL);
       
   200 
       
   201     visitor = NW_LMgr_ContainerBox_GetBoxVisitor(box);
       
   202     NW_THROW_OOM_ON_NULL(visitor, status);
       
   203  
       
   204     /* Invoke base-class shift on this box and all children */
       
   205 
       
   206     while ((child = NW_LMgr_BoxVisitor_NextBox(visitor, NULL)) != NULL) {
       
   207       status = NW_LMgr_Box_Class.NW_LMgr_Box.shift(child, delta);
       
   208       _NW_THROW_ON_ERROR(status);
       
   209     }
       
   210   }
       
   211   NW_CATCH(status) {
       
   212   }
       
   213   NW_FINALLY {
       
   214     NW_Object_Delete(visitor);
       
   215     return status;
       
   216   }
       
   217   NW_END_TRY
       
   218 }
       
   219 
       
   220 /* ------------------------------------------------------------------------- *
       
   221  * Function:     NW_LMgr_ContainerBox_Clone
       
   222  * Description:  Clones of containers only inherit the property list.  They
       
   223  *               also have their "Clone" flag set.  The children are not 
       
   224  *               copied into the new box.
       
   225  * Returns:      The new box, or NULL in case of an error.
       
   226  */
       
   227 NW_LMgr_Box_t*
       
   228 _NW_LMgr_ContainerBox_Clone (NW_LMgr_Box_t* box)
       
   229 {
       
   230   NW_LMgr_Box_t *newBox = NULL;
       
   231 
       
   232   /* parameter assertion block */
       
   233   NW_ASSERT(NW_Object_IsInstanceOf (box, &NW_LMgr_ContainerBox_Class));
       
   234 
       
   235   /* Create the new box */
       
   236   newBox = (NW_LMgr_Box_t*) NW_LMgr_ContainerBox_New (0);
       
   237   if (newBox == NULL) {
       
   238     return NULL;
       
   239   }
       
   240 
       
   241   /* Copy the property list, if one exists */
       
   242   if (box->propList != NULL) {
       
   243     newBox->propList = NW_LMgr_PropertyList_Clone (box->propList);
       
   244   }
       
   245   else{
       
   246     /* instantiate a new SimplePropertyList object */
       
   247     newBox->propList = (NW_LMgr_PropertyList_t*)
       
   248               NW_LMgr_SlavePropertyList_New (NULL);
       
   249   }
       
   250   if (newBox->propList == NULL) {
       
   251     NW_Object_Delete (newBox);
       
   252     return NULL;
       
   253   }
       
   254 
       
   255   return newBox;
       
   256 }
       
   257 
       
   258 /* ------------------------------------------------------------------------- *
       
   259    public/protected final methods
       
   260  * ------------------------------------------------------------------------- */
       
   261 
       
   262 /* ------------------------------------------------------------------------- */
       
   263 TBrowserStatusCode
       
   264 NW_LMgr_ContainerBox_Collapse (NW_LMgr_ContainerBox_t* thisObj)
       
   265 {
       
   266   NW_LMgr_PropertyList_t* propertyList;
       
   267   NW_LMgr_Property_t prop;
       
   268   NW_LMgr_ContainerBox_t* siblingBox;
       
   269   NW_LMgr_Box_t* childBox;
       
   270   TBrowserStatusCode status = KBrsrSuccess;
       
   271 
       
   272   /* parameter assertion block */
       
   273   NW_ASSERT (NW_Object_IsInstanceOf (thisObj, &NW_LMgr_ContainerBox_Class));
       
   274 
       
   275   propertyList = NW_LMgr_Box_PropListGet(NW_LMgr_BoxOf(thisObj));
       
   276   if (propertyList == NULL){
       
   277     return KBrsrSuccess;
       
   278   }
       
   279 
       
   280   NW_ASSERT (NW_Object_IsInstanceOf (propertyList, &NW_LMgr_PropertyList_Class));
       
   281 
       
   282   /* the master box will take care of coolapsing the slave boxes */
       
   283   if (NW_Object_IsInstanceOf(propertyList, &NW_LMgr_SlavePropertyList_Class)){
       
   284     return KBrsrSuccess;
       
   285   }
       
   286 
       
   287   /* if the propertylist is not slave propertylist, it definitely is a simple
       
   288      property list, and this box is a master box - so start collapse
       
   289    */
       
   290 
       
   291   /* implement collapse */
       
   292 
       
   293   /* Get sibling box */
       
   294   prop.value.object = NULL;
       
   295   (void)NW_LMgr_PropertyList_Get(propertyList, NW_CSS_Prop_sibling, &prop);
       
   296   if (prop.value.object == NULL){
       
   297     return KBrsrSuccess;
       
   298   }
       
   299   
       
   300   while(prop.value.object)
       
   301   {
       
   302     NW_ADT_Vector_Metric_t childCount;
       
   303 
       
   304     siblingBox = NW_LMgr_ContainerBoxOf(prop.value.object);
       
   305 
       
   306     /* This condition should never happen unless sibling boxes are not created
       
   307     properly. Should it be an ASSERT instead?? */
       
   308     if (!NW_Object_IsInstanceOf(NW_LMgr_BoxOf(siblingBox)->propList, 
       
   309                                &NW_LMgr_SlavePropertyList_Class))
       
   310     {
       
   311       return KBrsrFailure;
       
   312     }
       
   313 
       
   314     /* Insert your sibling's children in master container box */
       
   315     /* PROBLEM: Make Container_GetChild recognize NW_ADT_Vector_AtEnd */
       
   316     childCount = NW_LMgr_ContainerBox_GetChildCount(siblingBox);
       
   317     while (childCount > 0)
       
   318     {
       
   319       childCount--;
       
   320       childBox = NW_LMgr_ContainerBox_GetChild(siblingBox, childCount);
       
   321       NW_ASSERT(childBox);
       
   322        
       
   323       /* Insert ChildAt will remove the child from the old parent 
       
   324          which is the sibling box
       
   325          */
       
   326       /* The following method should be more efficient - we get the child
       
   327          from the old box, and then again search for it to remove it. 
       
   328          RemoveChild should return a box, so that we can use that box to 
       
   329          attach it somewhere else */
       
   330       status = NW_LMgr_ContainerBox_InsertChildAt(thisObj, childBox, 0);
       
   331       if (status != KBrsrSuccess) {
       
   332         return status;
       
   333       }
       
   334 
       
   335     }
       
   336     
       
   337     /* Get next sibling box */
       
   338     propertyList = NW_LMgr_Box_PropListGet(NW_LMgr_BoxOf(siblingBox));
       
   339     NW_ASSERT (NW_Object_IsInstanceOf (propertyList, &NW_LMgr_PropertyList_Class));
       
   340 
       
   341     prop.value.object = NULL;
       
   342     (void)NW_LMgr_PropertyList_Get(propertyList, NW_CSS_Prop_sibling, &prop);
       
   343 
       
   344     /* delete the sibling box */
       
   345     NW_Object_Delete(siblingBox);
       
   346 
       
   347     /* If we come back in a loop to the master box, then stop */
       
   348     if (prop.value.object == thisObj)
       
   349       break;
       
   350   }
       
   351   /* We also want to remove the sibling property on the master box,
       
   352      since we are collapsing the split containers */
       
   353   (void)NW_LMgr_Box_RemoveProperty(NW_LMgr_BoxOf(thisObj), NW_CSS_Prop_sibling);
       
   354 
       
   355   return KBrsrSuccess;
       
   356 }
       
   357 
       
   358 /* ------------------------------------------------------------------------- *
       
   359  * Function:     NW_LMgr_ContainerBox_InsertChildAt     
       
   360  * Description:  Inserts a child at the given index.  If a child is already
       
   361  *               attached to a parent, it detaches it first.
       
   362  * Returns:      KBrsrSuccess if successful, KBrsrFailure if the index 
       
   363  *               is out of bounds, KBrsrOutOfMemory.
       
   364  */
       
   365 
       
   366 TBrowserStatusCode
       
   367 NW_LMgr_ContainerBox_InsertChildAt (NW_LMgr_ContainerBox_t* container,
       
   368                                     NW_LMgr_Box_t* child,
       
   369                                     NW_ADT_Vector_Metric_t where)
       
   370 {
       
   371   NW_LMgr_ContainerBox_t* parent;
       
   372 
       
   373   NW_TRY(status) {
       
   374 
       
   375     NW_ASSERT(child != NULL);
       
   376 
       
   377     /* Remove the child from its existing parent, if necessary */
       
   378     parent = NW_LMgr_Box_GetParent (child);
       
   379     if (parent != NULL) {
       
   380       status = NW_LMgr_ContainerBox_RemoveChild (parent, child);
       
   381       _NW_THROW_ON_ERROR(status);
       
   382     }
       
   383   
       
   384     /* Insert the child into our 'children' vector */
       
   385     NW_THROW_OOM_ON_NULL(NW_ADT_DynamicVector_InsertAt(container->children,
       
   386                                                        &child, where),
       
   387                          status);
       
   388 
       
   389     /* Set the parent field of the Box - note that we do this as
       
   390        a 'friend' class */
       
   391     NW_LMgr_Box_SetParent (child, container);
       
   392   }
       
   393   NW_CATCH(status) {
       
   394   }
       
   395   NW_FINALLY {
       
   396     return status;
       
   397   }
       
   398   NW_END_TRY
       
   399 }
       
   400 
       
   401 /* ------------------------------------------------------------------------- *
       
   402  * Function:     NW_LMgr_ContainerBox_AddChild   
       
   403  * Description:  Adds a child to the end of the container.
       
   404  * Returns:      KBrsrSuccess, KBrsrOutOfMemory.
       
   405  */
       
   406 
       
   407 TBrowserStatusCode
       
   408 NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBox_t* container,
       
   409                                NW_LMgr_Box_t* child)
       
   410 {
       
   411   return NW_LMgr_ContainerBox_InsertChildAt (container, child,
       
   412                                              NW_ADT_Vector_AtEnd);
       
   413 }
       
   414 
       
   415 /* ------------------------------------------------------------------------- *
       
   416  * Function:     NW_LMgr_ContainerBox_InsertChild
       
   417  * Description:  Inserts a child immediately before the box pointed to by
       
   418  *               "where".
       
   419  *               If "where" is not a child of the container, KBrsrFailure
       
   420  *               is returned.
       
   421  * Returns:      KBrsrSuccess, KBrsrFailure, KBrsrOutOfMemory.
       
   422  */
       
   423 
       
   424 TBrowserStatusCode
       
   425 NW_LMgr_ContainerBox_InsertChild (NW_LMgr_ContainerBox_t* container,
       
   426                                   NW_LMgr_Box_t* child,
       
   427                                   NW_LMgr_Box_t* where)
       
   428 {
       
   429   NW_ADT_Vector_Metric_t index;
       
   430 
       
   431   index = NW_ADT_Vector_GetElementIndex (container->children,
       
   432                                          &where);
       
   433   if (index == NW_ADT_Vector_AtEnd) {
       
   434     return KBrsrFailure;
       
   435   }
       
   436   return NW_LMgr_ContainerBox_InsertChildAt (container, child, index);
       
   437 }
       
   438 
       
   439 /* ------------------------------------------------------------------------- *
       
   440  * Function:     NW_LMgr_ContainerBox_InsertChildAft
       
   441  * Description:  Inserts a child immediately following the box pointed to by 
       
   442  *               "where".  If "where" is not a child of the container, 
       
   443  *               KBrsrFailure is returned.
       
   444  * Returns:      KBrsrSuccess, KBrsrFailure, KBrsrOutOfMemory.
       
   445  */
       
   446 
       
   447 TBrowserStatusCode
       
   448 NW_LMgr_ContainerBox_InsertChildAft (NW_LMgr_ContainerBox_t* container,
       
   449                                      NW_LMgr_Box_t* child,
       
   450                                      NW_LMgr_Box_t* where)
       
   451 {
       
   452   NW_ADT_Vector_Metric_t index;
       
   453 
       
   454   index = NW_ADT_Vector_GetElementIndex (container->children,
       
   455                                          &where);
       
   456   if (index == NW_ADT_Vector_AtEnd) {
       
   457     return KBrsrFailure; /* TODO: return a more descriptive error code */
       
   458   }
       
   459   if ((index + 1)
       
   460       < NW_ADT_Vector_GetSize(container->children)) {
       
   461     return NW_LMgr_ContainerBox_InsertChildAt (container, child, 
       
   462                                                ((NW_ADT_Vector_Metric_t)
       
   463                                                 (index+1)));
       
   464   } else {
       
   465     return NW_LMgr_ContainerBox_AddChild (container, child);
       
   466   }
       
   467 }
       
   468 
       
   469 /* ------------------------------------------------------------------------- *
       
   470  * Function:     NW_LMgr_ContainerBox_AppendChildrenOf   
       
   471  * Description:  Appends the children of "source" to the container pointed
       
   472  *               to by "container".
       
   473  * Returns:      KBrsrSuccess, KBrsrOutOfMemory.
       
   474  */
       
   475 
       
   476 TBrowserStatusCode
       
   477 NW_LMgr_ContainerBox_AppendChildrenOf (NW_LMgr_ContainerBox_t* container,
       
   478                                        NW_LMgr_ContainerBox_t* source)
       
   479 {
       
   480   NW_TRY(status) {
       
   481     while (NW_ADT_Vector_GetSize (source->children) != 0) {
       
   482       NW_LMgr_Box_t* child;
       
   483 
       
   484       child = *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (source->children, 0);
       
   485       NW_ASSERT(child != NULL);
       
   486 
       
   487       status = NW_LMgr_ContainerBox_AddChild (container, child);
       
   488       _NW_THROW_ON_ERROR(status);
       
   489     }
       
   490   }
       
   491   NW_CATCH(status) {
       
   492   }
       
   493   NW_FINALLY {
       
   494     return status;
       
   495   }
       
   496   NW_END_TRY
       
   497 }
       
   498 
       
   499 /* ------------------------------------------------------------------------- *
       
   500  * Function:     NW_LMgr_ContainerBox_ReplaceChild
       
   501  * Description:  Replaces "originalChild" with "newChild".
       
   502  * Returns:      KBrsrSuccess, KBrsrFailure if the original child
       
   503  *               is not inside "container", KBrsrOutOfMemory.
       
   504  */
       
   505 
       
   506 TBrowserStatusCode
       
   507 NW_LMgr_ContainerBox_ReplaceChild (NW_LMgr_ContainerBox_t* container,
       
   508                                    NW_LMgr_Box_t* originalChild,
       
   509                                    NW_LMgr_Box_t* newChild)
       
   510 {
       
   511   NW_ADT_Vector_Metric_t index;
       
   512 
       
   513   NW_TRY(status) {
       
   514     index = NW_ADT_Vector_GetElementIndex(container->children,
       
   515                                           &originalChild);
       
   516     if (index == NW_ADT_Vector_AtEnd) {
       
   517       NW_THROW_STATUS(status, KBrsrFailure);
       
   518     }
       
   519 
       
   520     status = NW_LMgr_ContainerBox_InsertChildAt (container, newChild, index);
       
   521     _NW_THROW_ON_ERROR(status);
       
   522 
       
   523     status = NW_LMgr_ContainerBox_RemoveChild (container, originalChild);
       
   524     _NW_THROW_ON_ERROR(status);
       
   525   }
       
   526   NW_CATCH(status) {
       
   527   }
       
   528   NW_FINALLY {
       
   529     return status;
       
   530   }
       
   531   NW_END_TRY
       
   532 }
       
   533 
       
   534 /* ------------------------------------------------------------------------- *
       
   535  * Function:     NW_LMgr_ContainerBox_GetChildIndex
       
   536  * Description:  Finds the index of "child" in the container.
       
   537  * Returns:      The index, or NW_ADT_Vector_AtEnd, if the child in not inside
       
   538  *               container.
       
   539  */
       
   540 
       
   541 NW_ADT_Vector_Metric_t
       
   542 NW_LMgr_ContainerBox_GetChildIndex (NW_LMgr_ContainerBox_t* container,
       
   543                                     NW_LMgr_Box_t* child)
       
   544 {
       
   545 
       
   546   return NW_ADT_Vector_GetElementIndex (container->children,
       
   547                                         &child);
       
   548 
       
   549 }
       
   550 
       
   551 /* ------------------------------------------------------------------------- *
       
   552  * Function:     NW_LMgr_ContainerBox_RemoveChild
       
   553  * Description:  Removes the child pointed to by "component" from the container.
       
   554  * Returns:      KBrsrSuccess, KBrsrFailure if the original child
       
   555  *               is not inside "container", KBrsrOutOfMemory.
       
   556  */
       
   557 
       
   558 TBrowserStatusCode
       
   559 NW_LMgr_ContainerBox_RemoveChild (NW_LMgr_ContainerBox_t* container,
       
   560                                   NW_LMgr_Box_t* component)
       
   561 {
       
   562   NW_TRY(status) {
       
   563     /* parameter assertion block */
       
   564     NW_ASSERT(NW_Object_IsInstanceOf (container, &NW_LMgr_ContainerBox_Class));
       
   565     NW_ASSERT(NW_Object_IsInstanceOf (component, &NW_LMgr_Box_Class));
       
   566 
       
   567     /* search the 'children' vector for the element */
       
   568     status = NW_ADT_DynamicVector_RemoveElement (container->children,
       
   569                                                  &component);
       
   570     _NW_THROW_ON_ERROR(status);
       
   571   
       
   572   /* clear the parent field of the component - note that we do this as a
       
   573   'friend' of the class */
       
   574     NW_LMgr_Box_SetParent (component, NULL);
       
   575   }
       
   576   NW_CATCH(status) {
       
   577   }
       
   578   NW_FINALLY {
       
   579     return status;
       
   580   }
       
   581   NW_END_TRY
       
   582 }
       
   583 
       
   584 /* ------------------------------------------------------------------------- */
       
   585 TBrowserStatusCode
       
   586 NW_LMgr_ContainerBox_RemoveChildren (NW_LMgr_ContainerBox_t* thisObj)
       
   587 {
       
   588   NW_ADT_VectorIterator_t iterator;
       
   589 
       
   590   NW_Object_Invalidate (&iterator);
       
   591   NW_TRY (status) {
       
   592     (void) NW_ADT_VectorIterator_Initialize (&iterator, thisObj->children,
       
   593                                              NW_ADT_Vector_AtFront,
       
   594                                              NW_ADT_Vector_AtEnd,
       
   595                                              NW_ADT_IteratorDirection_Increment);
       
   596 
       
   597     while (NW_ADT_Iterator_HasMoreElements (&iterator)) {
       
   598       NW_LMgr_Box_t* child;
       
   599 
       
   600       status = NW_ADT_Iterator_GetNextElement (&iterator, &child);
       
   601       NW_THROW_ON_ERROR (status);
       
   602 
       
   603       status = NW_LMgr_ContainerBox_RemoveChild (thisObj, child);
       
   604       NW_THROW_ON_ERROR (status);
       
   605     }
       
   606   }
       
   607 
       
   608   NW_CATCH (status) { /* empty */ }
       
   609 
       
   610   NW_FINALLY {
       
   611     NW_Object_Terminate (&iterator);
       
   612     return status;
       
   613   } NW_END_TRY
       
   614 }
       
   615 
       
   616 /* ------------------------------------------------------------------------- */
       
   617 TBrowserStatusCode
       
   618 NW_LMgr_ContainerBox_DeleteChildren (NW_LMgr_ContainerBox_t* thisObj)
       
   619 {
       
   620   NW_LMgr_Box_t** child;
       
   621 
       
   622   NW_TRY (status) {
       
   623     while ((child = (NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (thisObj->children, 0)) != NULL) {
       
   624       status = NW_LMgr_ContainerBox_RemoveChild (thisObj, *child);
       
   625       NW_THROW_ON_ERROR (status);
       
   626 
       
   627       NW_Object_Delete(*child);
       
   628     }
       
   629   }
       
   630 
       
   631   NW_CATCH (status) { /* empty */ }
       
   632 
       
   633   NW_FINALLY {
       
   634     return status;
       
   635   } NW_END_TRY
       
   636 }
       
   637 
       
   638 
       
   639 /* ------------------------------------------------------------------------- *
       
   640  * Function:     NW_LMgr_ContainerBox_GetChildCount
       
   641  * Description:  Counts the number of children of the container.
       
   642  * Returns:      The number of children, 0 if the container is empty.
       
   643  */
       
   644 
       
   645 NW_ADT_Vector_Metric_t
       
   646 NW_LMgr_ContainerBox_GetChildCount (NW_LMgr_ContainerBox_t* container)
       
   647 {
       
   648   return NW_ADT_Vector_GetSize (container->children);
       
   649 }
       
   650 
       
   651 /* ------------------------------------------------------------------------- *
       
   652  * Function:     NW_LMgr_ContainerBox_GetChild
       
   653  * Description:  Gets the child at "index".  
       
   654  * Returns:      The child box, or NULL if the index is out of bounds.
       
   655  */
       
   656 
       
   657 NW_LMgr_Box_t*
       
   658 NW_LMgr_ContainerBox_GetChild (NW_LMgr_ContainerBox_t* container,
       
   659                                NW_ADT_Vector_Metric_t index)
       
   660 {
       
   661   NW_LMgr_Box_t** entry;
       
   662 
       
   663   entry =
       
   664     (NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (container->children, index);
       
   665   if (entry != NULL) {
       
   666     return *entry;
       
   667   }
       
   668   return NULL;
       
   669 }
       
   670 
       
   671 /* ------------------------------------------------------------------------- *
       
   672  * Function:     NW_LMgr_ContainerBox_SplitAtIndex
       
   673  * Description:  SplitAtIndex returns a clone of the container containing the
       
   674  *               first "index" children.  The remaining children stay in the 
       
   675  *               original container.  If "index" is 0, the split container
       
   676  *               will be empty.  If "index" points to the last child, the
       
   677  *               original container will remain empty.
       
   678  * Returns:      The split container, or NULL if an error occured.
       
   679  */
       
   680 
       
   681 NW_LMgr_Box_t*
       
   682 NW_LMgr_ContainerBox_SplitAtIndex (NW_LMgr_ContainerBox_t* container,
       
   683                                    NW_ADT_Vector_Metric_t index){
       
   684   NW_ADT_Vector_Metric_t childCount, childIndex;
       
   685   NW_LMgr_ContainerBox_t *splitContainer = NULL;
       
   686   NW_LMgr_Box_t *childBox;
       
   687   NW_LMgr_Property_t prop;
       
   688   NW_LMgr_PropertyValue_t dirValue;
       
   689   
       
   690   childCount = NW_LMgr_ContainerBox_GetChildCount (container);
       
   691 
       
   692   /* Verify input parameters */
       
   693   if (childCount <= 1 || index >= childCount) {
       
   694     NW_ASSERT(0);
       
   695     return NULL;
       
   696   }
       
   697 
       
   698   NW_TRY(status) {
       
   699     /* Get the text direction */
       
   700     dirValue.token = NW_CSS_PropValue_ltr;
       
   701     status = NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(container), 
       
   702                                           NW_CSS_Prop_textDirection, 
       
   703                                           NW_CSS_ValueType_Token,
       
   704                                           &dirValue);
       
   705     NW_THROW_ON(status, KBrsrOutOfMemory);
       
   706 
       
   707     /* Create the new container */
       
   708     splitContainer =
       
   709       (NW_LMgr_ContainerBox_t*)NW_LMgr_Box_Clone ((NW_LMgr_Box_t*)container);
       
   710     NW_THROW_OOM_ON_NULL(splitContainer, status);
       
   711 
       
   712   /* Move children to the new container */
       
   713     for (childIndex = 0; childIndex < index; childIndex++) {
       
   714       childBox = NW_LMgr_ContainerBox_GetChild(container, 0);
       
   715 
       
   716       /* AddChild will remove the child from the old parent */
       
   717       status = NW_LMgr_ContainerBox_AddChild(splitContainer, childBox);
       
   718       _NW_THROW_ON_ERROR(status);
       
   719     }
       
   720 
       
   721   /* Get and set sibling property on the cloned box's property list */
       
   722   prop.value.object = NULL;
       
   723   (void)NW_LMgr_Box_GetPropertyFromList(NW_LMgr_BoxOf(container), 
       
   724                                         NW_CSS_Prop_sibling, &prop);
       
   725   if (prop.value.object == NULL){
       
   726     /* Set sibling property on the cloned box's property list */
       
   727     prop.type = NW_ADT_ValueType_Object | NW_CSS_ValueType_Copy;
       
   728     prop.value.object = container;
       
   729     status = NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(splitContainer), 
       
   730                                      NW_CSS_Prop_sibling, &prop);
       
   731     NW_ASSERT (status == KBrsrSuccess);
       
   732   }
       
   733 
       
   734   /* Set sibling property on the master box's property list */
       
   735   prop.type = NW_ADT_ValueType_Object | NW_CSS_ValueType_Copy;
       
   736   prop.value.object = splitContainer;
       
   737   status = NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(container), 
       
   738                                    NW_CSS_Prop_sibling, &prop);
       
   739   NW_ASSERT (status == KBrsrSuccess);
       
   740 
       
   741 #if 0
       
   742 #pragma message (__FILE__ ": ::MEMO::BE AWARE that this code should be commented out. It does exist in CORE.")
       
   743 // If this code is added LTR support should be added too
       
   744     status = NW_LMgr_Box_SetProperty((NW_LMgr_Box_t*)splitContainer, 
       
   745                                      NW_CSS_Prop_rightPadding, 
       
   746                                      &prop);
       
   747     _NW_THROW_ON_ERROR(status);
       
   748     status = NW_LMgr_Box_SetProperty((NW_LMgr_Box_t*)splitContainer, 
       
   749                                      NW_CSS_Prop_rightMargin, 
       
   750                                      &prop);
       
   751     _NW_THROW_ON_ERROR(status);
       
   752     status = NW_LMgr_Box_SetProperty((NW_LMgr_Box_t*)container, 
       
   753                                      NW_CSS_Prop_leftPadding, 
       
   754                                      &prop);
       
   755     _NW_THROW_ON_ERROR(status);
       
   756     status = NW_LMgr_Box_SetProperty((NW_LMgr_Box_t*)container, 
       
   757                                      NW_CSS_Prop_leftMargin, 
       
   758                                      &prop);
       
   759     _NW_THROW_ON_ERROR(status);
       
   760 #endif
       
   761   }
       
   762   NW_CATCH(status) {
       
   763     NW_Object_Delete(splitContainer);
       
   764 
       
   765     splitContainer = NULL;
       
   766   }
       
   767   NW_FINALLY {
       
   768     return (NW_LMgr_Box_t*)splitContainer;
       
   769   }
       
   770   NW_END_TRY
       
   771 }
       
   772 
       
   773 /* -------------------------------------------------------------------------- *
       
   774  * Function:     NW_LMgr_ContainerBox_GetBaseline
       
   775  * Description:  Returns the baseline of the container.
       
   776  *               According to the CSS spec, the baseline for boxes containing 
       
   777  *               multiple lines of text is the baseline of the first line of
       
   778  *               text. 
       
   779  *               We assume here that this also applies to boxes that contain
       
   780  *               mixed text and other content: i.e. that this applies to all
       
   781  *               containers by default.
       
   782  * Returns:      The baseline of the first child, or 0 if the container is
       
   783  *               empty.
       
   784  */
       
   785 
       
   786 /* TODO:  The box may not begin at the top of the container, so its baseline
       
   787  * BUG!   might be larger than is currently calculated. 
       
   788  */
       
   789 
       
   790 NW_GDI_Metric_t
       
   791 _NW_LMgr_ContainerBox_GetBaseline(NW_LMgr_Box_t* box)
       
   792 {
       
   793   NW_LMgr_Box_t *firstChild;
       
   794 
       
   795   if (NW_LMgr_ContainerBox_GetChildCount(NW_LMgr_ContainerBoxOf(box)) != 0){
       
   796     firstChild = NW_LMgr_ContainerBox_GetChild(NW_LMgr_ContainerBoxOf(box), 0);
       
   797     NW_ASSERT(firstChild != NULL);
       
   798     return NW_LMgr_Box_GetBaseline(firstChild);
       
   799   } else {
       
   800     return 0;
       
   801   }
       
   802 }
       
   803 
       
   804 /* -------------------------------------------------------------------------- *
       
   805  * Function:     NW_LMgr_ContainerBox_Render
       
   806  * Description:  Renders the container and its children.  
       
   807  * Returns:      KBrsrSuccess, KBrsrOutOfMemory
       
   808  */
       
   809 
       
   810 TBrowserStatusCode
       
   811 _NW_LMgr_ContainerBox_Render (NW_LMgr_Box_t* box,
       
   812                               CGDIDeviceContext* deviceContext,
       
   813                               NW_GDI_Rectangle_t* clipRect,
       
   814                               NW_LMgr_Box_t *currentBox,
       
   815                               NW_Uint8 flags,
       
   816                               NW_Bool* hasFocus,
       
   817                               NW_Bool* skipChildren,
       
   818                               NW_LMgr_RootBox_t *rootBox )
       
   819 {
       
   820   NW_GDI_Rectangle_t oldClip = {{0, 0}, {0, 0}};
       
   821   NW_GDI_Rectangle_t newClip;
       
   822   NW_GDI_Rectangle_t realClip;
       
   823   NW_GDI_Rectangle_t visibleArea;
       
   824   NW_GDI_Rectangle_t viewBounds;
       
   825   NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetDisplayBounds(box);
       
   826   NW_LMgr_PropertyValue_t value;
       
   827   NW_LMgr_PropertyValue_t floatVal;
       
   828   NW_LMgr_PropertyValue_t visibilityVal;
       
   829   NW_Bool clipRectChanged = NW_FALSE;
       
   830   NW_Bool containerVisible = NW_FALSE;
       
   831   void** ptr = NULL;
       
   832   NW_Bool cachePresent = NW_FALSE;
       
   833 
       
   834   NW_TRY(status) 
       
   835   {
       
   836     // Should we draw floats? 
       
   837     if (!(flags & NW_LMgr_Box_Flags_DrawFloats)) 
       
   838       {
       
   839       floatVal.token = NW_CSS_PropValue_none;
       
   840       NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_float, NW_CSS_ValueType_Token, &floatVal);
       
   841       if (floatVal.token != NW_CSS_PropValue_none) 
       
   842         {
       
   843         NW_THROW_SUCCESS( status );
       
   844         }
       
   845       }
       
   846     // check if the this box has focus
       
   847     // if hasFocus is already set to true by any parent
       
   848     // then it should not be overuled.
       
   849     if( !(*hasFocus) && currentBox == box )
       
   850       {
       
   851       *hasFocus = NW_TRUE;
       
   852       }
       
   853     // Get the view bounds 
       
   854     viewBounds = *(deviceContext->DisplayBounds());
       
   855     viewBounds.point = *(deviceContext->Origin());
       
   856 
       
   857     // Determine the part of the box within the clip.  
       
   858     if( !NW_GDI_Rectangle_Cross( clipRect, &boxBounds, &visibleArea ) ) 
       
   859       {
       
   860       // out of the view
       
   861       goto drawChildren;
       
   862       }
       
   863     // Is the box visible on-screen?  If not, stil try to draw
       
   864     // the children 
       
   865     if( !NW_GDI_Rectangle_Cross( &viewBounds, &visibleArea, NULL ) ) 
       
   866       {
       
   867       goto drawChildren;
       
   868       }
       
   869     // If the clip is not visible on-screen, we 
       
   870     // draw neither the Container nor its children;
       
   871     // in case we are calculating the extents, we will still
       
   872     // have to peek into all children 
       
   873     if (!NW_GDI_Rectangle_Cross( clipRect, &viewBounds, &realClip ) ) 
       
   874       {
       
   875       goto drawChildren;
       
   876       }
       
   877     
       
   878     // Save the old clip rect 
       
   879     oldClip = deviceContext->ClipRect();
       
   880     // Set the new clip rect 
       
   881     deviceContext->SetClipRect(  &realClip );
       
   882     clipRectChanged = NW_TRUE;
       
   883 
       
   884     // Check if visibility val is set to not visible.  In that case
       
   885     // we do not draw the Container, but we still try to draw the
       
   886     // children (the Visiblity prop may be overriden) 
       
   887     visibilityVal.token = NW_CSS_PropValue_visible;
       
   888     (void) NW_LMgr_Box_GetPropertyValue (box, NW_CSS_Prop_visibility,
       
   889                                          NW_CSS_ValueType_Token, &visibilityVal);
       
   890   
       
   891     if (visibilityVal.token != NW_CSS_PropValue_visible) 
       
   892       {
       
   893       goto drawChildren;
       
   894       }
       
   895 
       
   896     // make the box draw itself 
       
   897     status = NW_LMgr_Box_Draw( box, deviceContext, *hasFocus );
       
   898     containerVisible = NW_TRUE;
       
   899     _NW_THROW_ON_ERROR (status);
       
   900 
       
   901 	// Add the box and the clip to the cache 
       
   902     cachePresent = NW_LMgr_Box_Update_RenderCache (rootBox, box, &realClip, &ptr);
       
   903     if (cachePresent)
       
   904         {
       
   905 		NW_THROW_OOM_ON_NULL(ptr, status);
       
   906 		}
       
   907 
       
   908     // Even if the Container itself is not visible, its children
       
   909     // might be 
       
   910     // note that this is overruled in smallscreen mode as we do not
       
   911     // render any children of a non visible container.
       
   912 drawChildren:
       
   913  
       
   914     // Modify the clip rectangle, if necessary 
       
   915     newClip = *clipRect;
       
   916     value.token = NW_CSS_PropValue_visible;
       
   917     (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_overflow,
       
   918                                        NW_CSS_ValueType_Token, &value);
       
   919 
       
   920     if( value.token == NW_CSS_PropValue_hidden ) 
       
   921       {
       
   922       NW_LMgr_FrameInfo_t padding; 
       
   923       NW_LMgr_FrameInfo_t border;
       
   924       NW_GDI_Rectangle_t tempClip = boxBounds;
       
   925 
       
   926       NW_LMgr_Box_GetPadding( box, &padding, ELMgrFrameAll );
       
   927       NW_LMgr_Box_GetBorderWidth( box, &border, ELMgrFrameAll );
       
   928       tempClip.point.x = (NW_GDI_Metric_t)(boxBounds.point.x + padding.left
       
   929                                            + border.left);
       
   930       tempClip.point.y = (NW_GDI_Metric_t)(boxBounds.point.y + padding.top
       
   931                                            + border.top);
       
   932       tempClip.dimension.width = (NW_GDI_Metric_t)(boxBounds.dimension.width
       
   933                                                    - padding.left
       
   934                                                    - padding.right
       
   935                                                    - border.left - border.right);
       
   936       tempClip.dimension.height = (NW_GDI_Metric_t)(boxBounds.dimension.height
       
   937                                                     - padding.top
       
   938                                                     - padding.bottom
       
   939                                                     - border.top
       
   940                                                     - border.bottom);
       
   941 
       
   942       if (!NW_GDI_Rectangle_Cross(&tempClip, clipRect, &newClip)) 
       
   943         {
       
   944         // children are out of view
       
   945         containerVisible = NW_FALSE;
       
   946         NW_THROW_SUCCESS(status);
       
   947         }
       
   948       else
       
   949         {
       
   950         // modify cliprect for the children.
       
   951   		  *clipRect = newClip;
       
   952         }
       
   953       }
       
   954     }
       
   955   NW_CATCH(status) 
       
   956     {
       
   957     }
       
   958   NW_FINALLY 
       
   959     {
       
   960     // skip children unless the container is visible
       
   961     *skipChildren = (NW_Bool)( containerVisible == NW_TRUE ? NW_FALSE : NW_TRUE );
       
   962     if( clipRectChanged == NW_TRUE )
       
   963       {
       
   964       /* Reset the clip rect */
       
   965       deviceContext->SetClipRect( &oldClip);
       
   966       }
       
   967     return status;
       
   968     }
       
   969   NW_END_TRY
       
   970   }
       
   971 
       
   972 /* ------------------------------------------------------------------------- *
       
   973  * Function:    NW_LMgr_ContainerBox_ResizeToChildren 
       
   974  * Description: Resize makes the container box just big enough to enclose all of 
       
   975  *              its children. Although the box is invisible and has no effect
       
   976  *              on the enclosing flow, these bounds are available to the
       
   977  *              UI event mechanism to identify which action container should
       
   978  *              handle an event. Note a limitation here: the container box
       
   979  *              can't actually do this correctly until the children have all
       
   980  *              been formatted: something the container can't really do itself
       
   981  *              because it lacks a formatting context. Since formatting contexts
       
   982  *              are not attached to boxes, there is no way to walk up the
       
   983  *              tree looking for one either. 
       
   984  * Returns:     KBrsrSuccess
       
   985  */
       
   986 
       
   987 TBrowserStatusCode
       
   988 NW_LMgr_ContainerBox_ResizeToChildren(NW_LMgr_ContainerBox_t* container)
       
   989 {
       
   990   NW_ADT_Vector_Metric_t numChildren;
       
   991   NW_LMgr_Box_t* thisBox = NW_LMgr_BoxOf(container);
       
   992   NW_ADT_Vector_Metric_t index;
       
   993   const NW_ADT_Vector_t *children;
       
   994   NW_LMgr_PropertyValue_t propValue;
       
   995   NW_LMgr_FrameInfo_t borders, padding;
       
   996   NW_GDI_Rectangle_t containerBounds = NW_LMgr_Box_GetFormatBounds(thisBox);
       
   997   NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( thisBox );
       
   998   TBrowserStatusCode status = KBrsrSuccess;
       
   999    NW_Bool FirstVisibleChild = NW_TRUE;
       
  1000 
       
  1001   NW_ASSERT(container != NULL);
       
  1002   
       
  1003   children = NW_LMgr_ContainerBox_GetChildren(container);
       
  1004 
       
  1005   numChildren = NW_ADT_Vector_GetSize(children);
       
  1006    
       
  1007   // Initialize the values for the case there are no visible children.
       
  1008   containerBounds.point.x = containerBounds.point.y = 0;
       
  1009   containerBounds.dimension.width = containerBounds.dimension.height = 0;
       
  1010   NW_LMgr_Box_SetFormatBounds( thisBox, containerBounds );
       
  1011 
       
  1012   for (index = 0; index < numChildren; index++) {
       
  1013     NW_LMgr_Box_t* child;
       
  1014     
       
  1015     child = *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (children, index);
       
  1016     containerBounds = NW_LMgr_Box_GetFormatBounds(thisBox);
       
  1017 
       
  1018     // If the child box is not displayable, ignore it.
       
  1019     propValue.token = NW_CSS_PropValue_display_inline;
       
  1020     NW_LMgr_Box_GetPropertyValue(child, NW_CSS_Prop_display, NW_CSS_ValueType_Token, &propValue);
       
  1021     if (propValue.token == NW_CSS_PropValue_none){
       
  1022       continue;
       
  1023       }
       
  1024     
       
  1025     // This step is skipped in vertical layout mode (see the comment in 
       
  1026     // CLMgr_BoxFormatHandler::UpdateDisplayBounds) or if the child is an object-box.
       
  1027     // Object-boxes are always paired with a container-box that has it as the 
       
  1028     // only child.  Because of this it should never skip the object-box -- otherwise
       
  1029     // the container-box will have 0,0 dimensions.
       
  1030     //if( !NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) && !ObjectUtils::IsObjectBox(*child, EFalse))
       
  1031     //    {
       
  1032         // If the child box is a float, ignore it.
       
  1033     //    propValue.token = NW_CSS_PropValue_none;
       
  1034     //    NW_LMgr_Box_GetPropertyValue(child, NW_CSS_Prop_float, NW_CSS_ValueType_Token, &propValue);
       
  1035     //    if (propValue.token != NW_CSS_PropValue_none)
       
  1036     //        {
       
  1037     //        continue;
       
  1038     //        }
       
  1039     //    }
       
  1040     
       
  1041     // If the child box is a container that has no visible children, ignore it.
       
  1042     NW_GDI_Rectangle_t childBoxBounds = NW_LMgr_Box_GetFormatBounds( child );
       
  1043     if ((childBoxBounds.dimension.height == 0) && (childBoxBounds.dimension.width == 0)){
       
  1044        if (NW_Object_IsInstanceOf(child, &NW_LMgr_ContainerBox_Class)){
       
  1045         continue;
       
  1046         }
       
  1047       }
       
  1048     
       
  1049     if(FirstVisibleChild){
       
  1050 		FirstVisibleChild = NW_FALSE;
       
  1051       NW_LMgr_Box_SetFormatBounds( NW_LMgr_BoxOf( container ), childBoxBounds );
       
  1052       }
       
  1053     else{
       
  1054       if(childBoxBounds.point.x < containerBounds.point.x){
       
  1055         containerBounds.point.x = childBoxBounds.point.x;
       
  1056         NW_LMgr_Box_SetFormatBounds( thisBox, containerBounds );
       
  1057         }
       
  1058       
       
  1059       if(childBoxBounds.point.y < containerBounds.point.y){
       
  1060         containerBounds.point.y = childBoxBounds.point.y;
       
  1061         NW_LMgr_Box_SetFormatBounds( thisBox, containerBounds );
       
  1062         }
       
  1063       
       
  1064       if((childBoxBounds.point.x + childBoxBounds.dimension.width) >
       
  1065         (containerBounds.point.x + containerBounds.dimension.width)){
       
  1066           containerBounds.dimension.width = (NW_GDI_Metric_t)
       
  1067           (childBoxBounds.point.x + childBoxBounds.dimension.width - 
       
  1068              containerBounds.point.x);
       
  1069           NW_LMgr_Box_SetFormatBounds( thisBox, containerBounds );
       
  1070         }
       
  1071       
       
  1072       if((childBoxBounds.point.y + childBoxBounds.dimension.height) >
       
  1073         (containerBounds.point.y + containerBounds.dimension.height)){
       
  1074           containerBounds.dimension.height = (NW_GDI_Metric_t)
       
  1075           (childBoxBounds.point.y + childBoxBounds.dimension.height - 
       
  1076              containerBounds.point.y);
       
  1077           NW_LMgr_Box_SetFormatBounds( thisBox, containerBounds );
       
  1078         }
       
  1079       }
       
  1080     }
       
  1081   containerBounds = NW_LMgr_Box_GetFormatBounds(thisBox);
       
  1082 
       
  1083   if ((containerBounds.dimension.width != 0) && 
       
  1084       (containerBounds.dimension.height != 0)) {
       
  1085     /* Now take into account the borders and padding */
       
  1086     NW_LMgr_Box_GetBorderWidth(thisBox, &borders, ELMgrFrameAll );
       
  1087     NW_LMgr_Box_GetPadding(thisBox, &padding, ELMgrFrameAll );
       
  1088     containerBounds.point.x = (NW_GDI_Metric_t)(containerBounds.point.x - borders.left - padding.left);
       
  1089     containerBounds.point.y = (NW_GDI_Metric_t)(containerBounds.point.y - borders.top - padding.top);
       
  1090     containerBounds.dimension.width = (NW_GDI_Metric_t)(containerBounds.dimension.width + 
       
  1091       borders.left + padding.left + borders.right + padding.right);
       
  1092     containerBounds.dimension.height = (NW_GDI_Metric_t)(containerBounds.dimension.height + 
       
  1093       borders.top + padding.top + borders.bottom + padding.bottom);
       
  1094     }
       
  1095   NW_LMgr_Box_SetFormatBounds( thisBox, containerBounds );
       
  1096   return status;
       
  1097 }
       
  1098 
       
  1099 /* ------------------------------------------------------------------------- *
       
  1100  * Function:     NW_LMgr_ContainerBox_Initialize
       
  1101  * A public method to add any anonymous block container boxes to
       
  1102  * a block container that contains both block and inline content.
       
  1103  * This assures that all content in a block box participates
       
  1104  * in the same format context (either block or inline).  This becomes
       
  1105  * essential when margins are collapsed.  CSS2 p98.
       
  1106  */
       
  1107 
       
  1108 TBrowserStatusCode
       
  1109 NW_LMgr_ContainerBox_Initialize(NW_LMgr_ContainerBox_t *container)
       
  1110     {
       
  1111     NW_TRY (status) 
       
  1112         {
       
  1113         NW_ADT_Vector_Metric_t index;
       
  1114         const NW_ADT_Vector_t *children;
       
  1115         NW_LMgr_Box_t* child;
       
  1116         NW_LMgr_ContainerBox_t *newContainer;
       
  1117         NW_LMgr_PropertyValue_t floatVal;
       
  1118 
       
  1119         children = NW_LMgr_ContainerBox_GetChildren(container);
       
  1120 
       
  1121         index = 0;
       
  1122         while (index < NW_ADT_Vector_GetSize(children)) {
       
  1123 
       
  1124         child = *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (children, index);
       
  1125 
       
  1126         if (NW_Object_IsInstanceOf(child, &NW_LMgr_SplitTextBox_Class)) 
       
  1127           {
       
  1128             NW_Object_Delete(child);
       
  1129             child = NULL;
       
  1130             continue;
       
  1131           }
       
  1132 
       
  1133         else if (NW_Object_IsInstanceOf(child, &NW_LMgr_AbstractTextBox_Class))
       
  1134             {
       
  1135             if( NW_LMgr_AbstractTextBox_IsBlank(NW_LMgr_AbstractTextBoxOf(child)) )
       
  1136                 {
       
  1137                 NW_Object_Delete(child);
       
  1138                 child = NULL;
       
  1139                 continue;
       
  1140                 }
       
  1141             }
       
  1142 
       
  1143         else if (NW_Object_IsInstanceOf(child, &NW_LMgr_FlowBox_Class) ||
       
  1144           NW_Object_IsClass(child, &NW_LMgr_StaticTableBox_Class) ||
       
  1145           NW_Object_IsClass(child, &NW_LMgr_StaticTableRowBox_Class)) {
       
  1146 
       
  1147         floatVal.token = NW_CSS_PropValue_none;
       
  1148         status = NW_LMgr_Box_GetPropertyValue(child, NW_CSS_Prop_float, NW_CSS_ValueType_Token, &floatVal);
       
  1149         if (status == KBrsrOutOfMemory) {
       
  1150           return KBrsrOutOfMemory;
       
  1151         }
       
  1152 
       
  1153         if (floatVal.token == NW_CSS_PropValue_none) {
       
  1154 
       
  1155           newContainer = NW_LMgr_ContainerBox_New(0);
       
  1156           NW_THROW_OOM_ON_NULL(newContainer, status);
       
  1157 
       
  1158           status = NW_LMgr_ContainerBox_AppendChildrenOf(newContainer, NW_LMgr_ContainerBoxOf(child));
       
  1159           _NW_THROW_ON_ERROR(status);
       
  1160 
       
  1161           status = NW_LMgr_ContainerBox_ReplaceChild(container, child, NW_LMgr_BoxOf(newContainer));
       
  1162           _NW_THROW_ON_ERROR(status);
       
  1163 
       
  1164           (void) NW_LMgr_Box_SetPropList(NW_LMgr_BoxOf(newContainer), NW_LMgr_Box_PropListGet(child));
       
  1165           (void) NW_LMgr_Box_SetPropList(child, NULL);
       
  1166           NW_LMgr_Box_RemoveProperty(NW_LMgr_BoxOf(newContainer), NW_CSS_Prop_display);
       
  1167           NW_LMgr_Box_RemoveProperty(NW_LMgr_BoxOf(newContainer), NW_CSS_Prop_float);
       
  1168 
       
  1169           NW_Object_Delete(child);
       
  1170           child = NULL;
       
  1171         }
       
  1172         }
       
  1173 
       
  1174         index ++;
       
  1175         }
       
  1176 
       
  1177     } NW_CATCH (status) {
       
  1178     } NW_FINALLY {
       
  1179     return KBrsrSuccess;
       
  1180     } NW_END_TRY
       
  1181     }
       
  1182 
       
  1183 /* ------------------------------------------------------------------------- *
       
  1184  * Function:     NW_LMgr_ContainerBox_InitializeSSL
       
  1185  * A public method to remove empty text child box in small screen mode
       
  1186  */
       
  1187 
       
  1188 TBrowserStatusCode
       
  1189 NW_LMgr_ContainerBox_InitializeSSL(NW_LMgr_ContainerBox_t *container)
       
  1190     {
       
  1191     TBrowserStatusCode status = KBrsrSuccess;
       
  1192     NW_ADT_Vector_Metric_t index;
       
  1193     const NW_ADT_Vector_t *children;
       
  1194     NW_LMgr_Box_t* child;
       
  1195 
       
  1196     children = NW_LMgr_ContainerBox_GetChildren(container);
       
  1197 
       
  1198     index = 0;
       
  1199     while (index < NW_ADT_Vector_GetSize(children)) 
       
  1200         {
       
  1201         child = *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (children, index);
       
  1202 
       
  1203         if (NW_Object_IsInstanceOf(child, &NW_LMgr_AbstractTextBox_Class))
       
  1204             {
       
  1205             if( NW_LMgr_AbstractTextBox_IsBlank(NW_LMgr_AbstractTextBoxOf(child)) )
       
  1206                 {
       
  1207                 NW_Object_Delete(child);
       
  1208                 child = NULL;
       
  1209                 continue;
       
  1210                 }
       
  1211             }
       
  1212         index ++;
       
  1213         }
       
  1214 
       
  1215     return status;
       
  1216     }
       
  1217 
       
  1218 NW_Bool NW_LMgr_ContainerBox_IsLastChild(NW_LMgr_Box_t* box)
       
  1219     {
       
  1220     return box == NW_LMgr_BoxOf(NW_LMgr_ContainerBox_GetChild(NW_LMgr_Box_GetParent((box)),
       
  1221                                 (NW_ADT_Vector_Metric_t) (NW_LMgr_ContainerBox_GetChildCount(NW_LMgr_Box_GetParent((box))) - 1 )));
       
  1222     }
       
  1223 
       
  1224 /* ------------------------------------------------------------------------- *
       
  1225   convenience functions
       
  1226  * ------------------------------------------------------------------------- */
       
  1227 
       
  1228 /* ------------------------------------------------------------------------- */
       
  1229 NW_LMgr_ContainerBox_t*
       
  1230 NW_LMgr_ContainerBox_New (NW_ADT_Vector_Metric_t numProperties)
       
  1231 {
       
  1232   return (NW_LMgr_ContainerBox_t*)
       
  1233     NW_Object_New (&NW_LMgr_ContainerBox_Class, numProperties);
       
  1234 }
       
  1235 
       
  1236 
       
  1237 
       
  1238 
       
  1239