Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Protected Member Functions | Friends
nsGridRowLayout Class Reference

#include <nsGridRowLayout.h>

Inheritance diagram for nsGridRowLayout:
Inheritance graph
[legend]
Collaboration diagram for nsGridRowLayout:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD 
CastToRowGroupLayout (nsGridRowGroupLayout **aRowGroup)
NS_IMETHOD CastToGridLayout (nsGridLayout2 **aGrid)
NS_IMETHOD GetGrid (nsIBox *aBox, nsGrid **aList, PRInt32 *aIndex, nsGridRowLayout *aRequestor=nsnull)
NS_IMETHOD GetParentGridPart (nsIBox *aBox, nsIBox **aParentBox, nsIGridPart **aParentGridRow)
NS_IMETHOD ChildrenInserted (nsIBox *aBox, nsBoxLayoutState &aState, nsIBox *aPrevBox, nsIBox *aChildList)
NS_IMETHOD ChildrenAppended (nsIBox *aBox, nsBoxLayoutState &aState, nsIBox *aChildList)
NS_IMETHOD ChildrenRemoved (nsIBox *aBox, nsBoxLayoutState &aState, nsIBox *aChildList)
NS_IMETHOD ChildrenSet (nsIBox *aBox, nsBoxLayoutState &aState, nsIBox *aChildList)
NS_IMETHOD GetTotalMargin (nsIBox *aBox, nsMargin &aMargin, PRBool aIsHorizontal)
NS_IMETHOD Layout (nsIBox *aBox, nsBoxLayoutState &aState)
NS_IMETHOD GetPrefSize (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, nsSize &aSize)
NS_IMETHOD GetMinSize (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, nsSize &aSize)
NS_IMETHOD GetMaxSize (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, nsSize &aSize)
NS_IMETHOD GetFlex (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, nscoord &aFlex)
NS_IMETHOD GetAscent (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, nscoord &aAscent)
NS_IMETHOD IsCollapsed (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, PRBool &aCollapsed)
NS_IMETHOD ChildBecameDirty (nsIBox *aBox, nsBoxLayoutState &aState, nsIBox *aChild)
NS_IMETHOD BecameDirty (nsIBox *aBox, nsBoxLayoutState &aState)
virtual void GetParentLayout (nsIBox *aBox, nsIBoxLayout **aParent)
virtual void AddBorderAndPadding (nsIBox *aBox, nsSize &aSize)
virtual void AddInset (nsIBox *aBox, nsSize &aSize)
virtual void AddMargin (nsIBox *aChild, nsSize &aSize)
virtual void AddMargin (nsSize &aSize, const nsMargin &aMargin)
NS_IMETHOD CountRowsColumns (nsIBox *aBox, PRInt32 &aRowCount, PRInt32 &aComputedColumnCount)=0
NS_IMETHOD DirtyRows (nsIBox *aBox, nsBoxLayoutState &aState)=0
NS_IMETHOD BuildRows (nsIBox *aBox, nsGridRow *aRows, PRInt32 *aCount)=0
NS_IMETHOD GetRowCount (PRInt32 &aRowCount)=0

Static Public Member Functions

static void Shutdown ()
static PRBool IsHorizontal (nsIBox *aBox)
static void SetLargestSize (nsSize &aSize1, const nsSize &aSize2, PRBool aIsHorizontal)
static void SetSmallestSize (nsSize &aSize1, const nsSize &aSize2, PRBool aIsHorizontal)
static void AddLargestSize (nsSize &aSize, const nsSize &aSizeToAdd, PRBool aIsHorizontal)
static void AddLargestSize (nsSize &aSize, const nsSize &aToAdd)
static void AddSmallestSize (nsSize &aSize, const nsSize &aSizeToAdd, PRBool aIsHorizontal)
static void AddSmallestSize (nsSize &aSize, const nsSize &aToAdd)
static void AddCoord (nscoord &aCoord, nscoord aCoordToAdd)

Protected Member Functions

NS_IMETHOD ChildAddedOrRemoved (nsIBox *aBox, nsBoxLayoutState &aState)=0
 nsGridRowLayout (nsIPresShell *aShell)
virtual void ComputeChildsNextPosition (nsIBox *aBox, nsIBox *aChild, nscoord &aCurX, nscoord &aCurY, nscoord &aNextX, nscoord &aNextY, const nsRect &aChildSize, const nsRect &aContainingRect, nscoord childAscent, nscoord aMaxAscent)
virtual void ChildResized (nsIBox *aBox, nsBoxLayoutState &aState, nsIBox *aChild, nsBoxSize *aChildBoxSize, nsComputedBoxSize *aChildComputedBoxSize, nsBoxSize *aBoxSizes, nsComputedBoxSize *aComputedBoxSizes, const nsRect &aChildLayoutRect, nsRect &aChildActualRect, nsRect &aContainingRect, PRInt32 aFlexes, PRBool &aFinished)
virtual void ComputeChildSizes (nsIBox *aBox, nsBoxLayoutState &aState, nscoord &aGivenSize, nsBoxSize *aBoxSizes, nsComputedBoxSize *&aComputedBoxSizes)
virtual void PopulateBoxSizes (nsIBox *aBox, nsBoxLayoutState &aBoxLayoutState, nsBoxSize *&aBoxSizes, nsComputedBoxSize *&aComputedBoxSizes, nscoord &aMinSize, nscoord &aMaxSize, PRInt32 &aFlexes)
virtual void InvalidateComputedSizes (nsComputedBoxSize *aComputedBoxSizes)
virtual PRBool GetDefaultFlex (PRInt32 &aFlex)
virtual void GetFrameState (nsIBox *aBox, nsFrameState &aState)

Friends

nsresult NS_NewSprocketLayout (nsIPresShell *aPresShell, nsCOMPtr< nsIBoxLayout > &aNewLayout)

Detailed Description

Definition at line 56 of file nsGridRowLayout.h.


Constructor & Destructor Documentation

Definition at line 52 of file nsGridRowLayout.cpp.


Member Function Documentation

void nsBoxLayout::AddBorderAndPadding ( nsIBox *  aBox,
nsSize aSize 
) [virtual, inherited]

Definition at line 76 of file nsBoxLayout.cpp.

{
  nsBox::AddBorderAndPadding(aBox, aSize);
}

Here is the caller graph for this function:

void nsSprocketLayout::AddCoord ( nscoord aCoord,
nscoord  aCoordToAdd 
) [static, inherited]

Definition at line 1662 of file nsSprocketLayout.cpp.

{
  if (aCoord != NS_INTRINSICSIZE) 
  {
    if (aCoordToAdd == NS_INTRINSICSIZE)
      aCoord = aCoordToAdd;
    else
      aCoord += aCoordToAdd;
  }
}

Here is the caller graph for this function:

void nsBoxLayout::AddInset ( nsIBox *  aBox,
nsSize aSize 
) [virtual, inherited]

Definition at line 94 of file nsBoxLayout.cpp.

{
  nsBox::AddInset(aBox, aSize);
}

Here is the caller graph for this function:

void nsBoxLayout::AddLargestSize ( nsSize aSize,
const nsSize aToAdd 
) [static, inherited]

Definition at line 159 of file nsBoxLayout.cpp.

{
  if (aSize2.width > aSize.width)
     aSize.width = aSize2.width;

  if (aSize2.height > aSize.height)
     aSize.height = aSize2.height;
}

Here is the caller graph for this function:

void nsSprocketLayout::AddLargestSize ( nsSize aSize,
const nsSize aSizeToAdd,
PRBool  aIsHorizontal 
) [static, inherited]

Definition at line 1651 of file nsSprocketLayout.cpp.

{
  if (aIsHorizontal)
    AddCoord(aSize.width, aSizeToAdd.width);
  else
    AddCoord(aSize.height, aSizeToAdd.height);

  SetLargestSize(aSize, aSizeToAdd, aIsHorizontal);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsBoxLayout::AddMargin ( nsIBox *  aChild,
nsSize aSize 
) [virtual, inherited]

Definition at line 82 of file nsBoxLayout.cpp.

{
  nsBox::AddMargin(aBox, aSize);
}

Here is the caller graph for this function:

void nsBoxLayout::AddMargin ( nsSize aSize,
const nsMargin aMargin 
) [virtual, inherited]

Definition at line 88 of file nsBoxLayout.cpp.

{
  nsBox::AddMargin(aSize, aMargin);
}

Here is the call graph for this function:

void nsBoxLayout::AddSmallestSize ( nsSize aSize,
const nsSize aToAdd 
) [static, inherited]

Definition at line 169 of file nsBoxLayout.cpp.

{
  if (aSize2.width < aSize.width)
     aSize.width = aSize2.width;

  if (aSize2.height < aSize.height)
     aSize.height = aSize2.height;
}

Here is the caller graph for this function:

void nsSprocketLayout::AddSmallestSize ( nsSize aSize,
const nsSize aSizeToAdd,
PRBool  aIsHorizontal 
) [static, inherited]

Definition at line 1673 of file nsSprocketLayout.cpp.

{
  if (aIsHorizontal)
    AddCoord(aSize.width, aSizeToAdd.width);
  else
    AddCoord(aSize.height, aSizeToAdd.height);
    
  SetSmallestSize(aSize, aSizeToAdd, aIsHorizontal);
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP nsBoxLayout::BecameDirty ( nsIBox *  aBox,
nsBoxLayoutState aState 
) [virtual, inherited]

Implements nsIBoxLayout.

Reimplemented in nsGridRowLeafLayout.

Definition at line 209 of file nsBoxLayout.cpp.

{
  return NS_OK;
}
NS_IMETHOD nsIGridPart::BuildRows ( nsIBox *  aBox,
nsGridRow aRows,
PRInt32 aCount 
) [pure virtual, inherited]

Implements nsIGridPart.

Definition at line 195 of file nsGridRowLayout.cpp.

{
  (*aGridLayout) = nsnull;
  return NS_OK;
}

Implements nsIGridPart.

Reimplemented in nsGridRowGroupLayout.

Definition at line 188 of file nsGridRowLayout.cpp.

{
  (*aRowGroup) = nsnull;
  return NS_OK;
}
NS_IMETHOD nsGridRowLayout::ChildAddedOrRemoved ( nsIBox *  aBox,
nsBoxLayoutState aState 
) [protected, pure virtual]

Implemented in nsGridRowGroupLayout, and nsGridRowLeafLayout.

Here is the caller graph for this function:

NS_IMETHODIMP nsBoxLayout::ChildBecameDirty ( nsIBox *  aBox,
nsBoxLayoutState aState,
nsIBox *  aChild 
) [virtual, inherited]

Implements nsIBoxLayout.

Reimplemented in nsGridRowLeafLayout.

Definition at line 203 of file nsBoxLayout.cpp.

{
  return NS_OK;
}
NS_IMETHODIMP nsGridRowLayout::ChildrenAppended ( nsIBox *  aBox,
nsBoxLayoutState aState,
nsIBox *  aChildList 
) [virtual]

Reimplemented from nsBoxLayout.

Definition at line 63 of file nsGridRowLayout.cpp.

{
  return ChildAddedOrRemoved(aBox, aState);
}

Here is the call graph for this function:

NS_IMETHODIMP nsGridRowLayout::ChildrenInserted ( nsIBox *  aBox,
nsBoxLayoutState aState,
nsIBox *  aPrevBox,
nsIBox *  aChildList 
) [virtual]

Reimplemented from nsBoxLayout.

Definition at line 57 of file nsGridRowLayout.cpp.

{
  return ChildAddedOrRemoved(aBox, aState);
}

Here is the call graph for this function:

NS_IMETHODIMP nsGridRowLayout::ChildrenRemoved ( nsIBox *  aBox,
nsBoxLayoutState aState,
nsIBox *  aChildList 
) [virtual]

Reimplemented from nsBoxLayout.

Definition at line 69 of file nsGridRowLayout.cpp.

{
  return ChildAddedOrRemoved(aBox, aState);
}

Here is the call graph for this function:

NS_IMETHODIMP nsGridRowLayout::ChildrenSet ( nsIBox *  aBox,
nsBoxLayoutState aState,
nsIBox *  aChildList 
) [virtual]

Reimplemented from nsBoxLayout.

Definition at line 75 of file nsGridRowLayout.cpp.

{
  return ChildAddedOrRemoved(aBox, aState);
}

Here is the call graph for this function:

void nsSprocketLayout::ChildResized ( nsIBox *  aBox,
nsBoxLayoutState aState,
nsIBox *  aChild,
nsBoxSize aChildBoxSize,
nsComputedBoxSize aChildComputedBoxSize,
nsBoxSize aBoxSizes,
nsComputedBoxSize aComputedBoxSizes,
const nsRect aChildLayoutRect,
nsRect aChildActualRect,
nsRect aContainingRect,
PRInt32  aFlexes,
PRBool aFinished 
) [protected, virtual, inherited]

Definition at line 1047 of file nsSprocketLayout.cpp.

{
      nsRect childCurrentRect(aChildLayoutRect);

      PRBool isHorizontal = IsHorizontal(aBox);
      nscoord childLayoutWidth  = GET_WIDTH(aChildLayoutRect,isHorizontal);
      nscoord& childActualWidth  = GET_WIDTH(aChildActualRect,isHorizontal);
      nscoord& containingWidth   = GET_WIDTH(aContainingRect,isHorizontal);   
      
      //nscoord childLayoutHeight = GET_HEIGHT(aChildLayoutRect,isHorizontal);
      nscoord& childActualHeight = GET_HEIGHT(aChildActualRect,isHorizontal);
      nscoord& containingHeight  = GET_HEIGHT(aContainingRect,isHorizontal);

      PRBool recompute = PR_FALSE;

      // if we are a horizontal box see if the child will fit inside us.
      if ( childActualHeight > containingHeight) {
            // if we are a horizontal box and the the child it bigger than our height

            // ok if the height changed then we need to reflow everyone but us at the new height
            // so we will set the changed index to be us. And signal that we need a new pass.

            nsSize max(0,0);
            nsSize min(0,0);
            aChild->GetMaxSize(aState, max);
            aChild->GetMinSize(aState, min);
            nsBox::BoundsCheckMinMax(min, max);
            AddMargin(aChild, max);

            if (isHorizontal)
              childActualHeight = max.height < childActualHeight ? max.height : childActualHeight;
            else
              childActualHeight = max.width < childActualHeight ? max.width : childActualHeight;

            // only set if it changes
            if (childActualHeight > containingHeight) {
                 containingHeight = childActualHeight;

              // remember we do not need to clear the resized list because changing the height of a horizontal box
              // will not affect the width of any of its children because block flow left to right, top to bottom. Just trust me
              // on this one.
              aFinished = PR_FALSE;

              // only recompute if there are flexes.
              if (aFlexes > 0) {
                // relayout everything
                recompute = PR_TRUE;
                InvalidateComputedSizes(aComputedBoxSizes);
                nsComputedBoxSize* node = aComputedBoxSizes;

                while(node) {
                  node->resized = PR_FALSE;
                  node = node->next;
                }

              }              
            }
      } 
      
      if (childActualWidth > childLayoutWidth) {
            nsSize max(0,0);
            nsSize min(0,0);
            aChild->GetMinSize(aState, min);
            aChild->GetMaxSize(aState, max);
            nsBox::BoundsCheckMinMax(min, max);
            AddMargin(aChild, max);

            // our width now becomes the new size

            if (isHorizontal)
              childActualWidth = max.width < childActualWidth ? max.width : childActualWidth;
            else
              childActualWidth = max.height < childActualWidth ? max.height : childActualWidth;

            if (childActualWidth > childLayoutWidth) {
               aChildComputedSize->size = childActualWidth;
               aChildBoxSize->min = childActualWidth;
               if (aChildBoxSize->pref < childActualWidth)
                  aChildBoxSize->pref = childActualWidth;

              // if we have flexible elements with us then reflex things. Otherwise we can skip doing it.
              if (aFlexes > 0) {
                InvalidateComputedSizes(aComputedBoxSizes);

                nsComputedBoxSize* node = aComputedBoxSizes;
                aChildComputedSize->resized = PR_TRUE;

                while(node) {
                  if (node->resized)
                      node->valid = PR_TRUE;
                
                  node = node->next;
                }

                recompute = PR_TRUE;
                aFinished = PR_FALSE;
              } else {
                containingWidth += aChildComputedSize->size - childLayoutWidth;
              }              
            }
      }

      if (recompute)
            ComputeChildSizes(aBox, aState, containingWidth, aBoxSizes, aComputedBoxSizes);

      if (childCurrentRect != aChildActualRect) {
        // the childRect includes the margin
        // make sure we remove it before setting 
        // the bounds.
        nsMargin margin(0,0,0,0);
        aChild->GetMargin(margin);
        nsRect rect(aChildActualRect);
        if (rect.width >= margin.left + margin.right && rect.height >= margin.top + margin.bottom) 
          rect.Deflate(margin);

        aChild->SetBounds(aState, rect);
        aChild->Layout(aState);
      }

}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsSprocketLayout::ComputeChildSizes ( nsIBox *  aBox,
nsBoxLayoutState aState,
nscoord aGivenSize,
nsBoxSize aBoxSizes,
nsComputedBoxSize *&  aComputedBoxSizes 
) [protected, virtual, inherited]

Reimplemented in nsGridRowLeafLayout.

Definition at line 1190 of file nsSprocketLayout.cpp.

{  

  //nscoord onePixel = aState.PresContext()->IntScaledPixelsToTwips(1);

  PRInt32 sizeRemaining            = aGivenSize;
  PRInt32 spacerConstantsRemaining = 0;

   // ----- calculate the spacers constants and the size remaining -----

  if (!aComputedBoxSizes)
      aComputedBoxSizes = new (aState) nsComputedBoxSize();
  
  nsBoxSize*         boxSizes = aBoxSizes;
  nsComputedBoxSize* computedBoxSizes = aComputedBoxSizes;
  PRInt32 count = 0;
  PRInt32 validCount = 0;

  while (boxSizes) 
  {

    NS_ASSERTION((boxSizes->min <= boxSizes->pref && boxSizes->pref <= boxSizes->max),"bad pref, min, max size");

    
     // ignore collapsed children
  //  if (boxSizes->collapsed) 
  //  {
    //  computedBoxSizes->valid = PR_TRUE;
    //  computedBoxSizes->size = boxSizes->pref;
     // validCount++;
  //      boxSizes->flex = 0;
   // }// else {
    
      if (computedBoxSizes->valid) { 
        sizeRemaining -= computedBoxSizes->size;
        validCount++;
      } else {
          if (boxSizes->flex == 0)
          {
            computedBoxSizes->valid = PR_TRUE;
            computedBoxSizes->size = boxSizes->pref;
            validCount++;
          }

          spacerConstantsRemaining += boxSizes->flex;
          sizeRemaining -= boxSizes->pref;
      }

      sizeRemaining -= (boxSizes->left + boxSizes->right);

    //} 

    boxSizes = boxSizes->next;

    if (boxSizes && !computedBoxSizes->next) 
      computedBoxSizes->next = new (aState) nsComputedBoxSize();

    computedBoxSizes = computedBoxSizes->next;
    count++;
  }

  // everything accounted for?
  if (validCount < count)
  {
    // ----- Ok we are give a size to fit into so stretch or squeeze to fit
    // ----- Make sure we look at our min and max size
    PRBool limit = PR_TRUE;
    for (int pass=1; PR_TRUE == limit; pass++) 
    {
      limit = PR_FALSE;
      boxSizes = aBoxSizes;
      computedBoxSizes = aComputedBoxSizes;

      while (boxSizes) { 

        // ignore collapsed spacers

   //    if (!boxSizes->collapsed) {
      
          nscoord pref = 0;
          nscoord max  = NS_INTRINSICSIZE;
          nscoord min  = 0;
          nscoord flex = 0;

          pref = boxSizes->pref;
          min  = boxSizes->min;
          max  = boxSizes->max;
          flex = boxSizes->flex;

          // ----- look at our min and max limits make sure we aren't too small or too big -----
          if (!computedBoxSizes->valid) {
            PRInt32 newSize = pref + sizeRemaining*flex/spacerConstantsRemaining; //NSToCoordRound(float((sizeRemaining*flex)/spacerConstantsRemaining));

            if (newSize<=min) {
              computedBoxSizes->size = min;
              computedBoxSizes->valid = PR_TRUE;
              spacerConstantsRemaining -= flex;
              sizeRemaining += pref;
              sizeRemaining -= min;
              limit = PR_TRUE;
            } else if (newSize>=max) {
              computedBoxSizes->size = max;
              computedBoxSizes->valid = PR_TRUE;
              spacerConstantsRemaining -= flex;
              sizeRemaining += pref;
              sizeRemaining -= max;
              limit = PR_TRUE;
            }
          }
       // }
        boxSizes         = boxSizes->next;
        computedBoxSizes = computedBoxSizes->next;
      }
    }
  }          

  // ---- once we have removed and min and max issues just stretch us out in the remaining space
  // ---- or shrink us. Depends on the size remaining and the spacer constants
  aGivenSize = 0;
  boxSizes = aBoxSizes;
  computedBoxSizes = aComputedBoxSizes;

  while (boxSizes) { 

    // ignore collapsed spacers
  //  if (!(boxSizes && boxSizes->collapsed)) {
    
      nscoord pref = 0;
      nscoord flex = 0;
      pref = boxSizes->pref;
      flex = boxSizes->flex;

      if (!computedBoxSizes->valid) {
        computedBoxSizes->size = pref + flex*sizeRemaining/spacerConstantsRemaining; //NSToCoordFloor(float((flex*sizeRemaining)/spacerConstantsRemaining));
        computedBoxSizes->valid = PR_TRUE;
      }

      aGivenSize += (boxSizes->left + boxSizes->right);
      aGivenSize += computedBoxSizes->size;

   // }

    boxSizes         = boxSizes->next;
    computedBoxSizes = computedBoxSizes->next;
  }
}

Here is the caller graph for this function:

void nsSprocketLayout::ComputeChildsNextPosition ( nsIBox *  aBox,
nsIBox *  aChild,
nscoord aCurX,
nscoord aCurY,
nscoord aNextX,
nscoord aNextY,
const nsRect aChildSize,
const nsRect aContainingRect,
nscoord  childAscent,
nscoord  aMaxAscent 
) [protected, virtual, inherited]

Definition at line 968 of file nsSprocketLayout.cpp.

{
  nsFrameState frameState = 0;
  GetFrameState(aBox, frameState);

  nsIBox::Halignment halign;
  nsIBox::Valignment valign;
  aBox->GetVAlign(valign);
  aBox->GetHAlign(halign);

  if (IsHorizontal(aBox)) {
    // Handle alignment of a horizontal box's children.
    if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
      aNextX = aCurX + aCurrentChildSize.width;
    else aNextX = aCurX - aCurrentChildSize.width;

    if (frameState & NS_STATE_AUTO_STRETCH)
      aCurY = aBoxRect.y;
    else {
      switch (valign) 
      {
         case nsBoxFrame::vAlign_BaseLine:
             aCurY = aBoxRect.y + (aMaxAscent - childAscent);
         break;

         case nsBoxFrame::vAlign_Top:
             aCurY = aBoxRect.y;
             break;
         case nsBoxFrame::vAlign_Middle:
             aCurY = aBoxRect.y + (aBoxRect.height/2 - aCurrentChildSize.height/2);
             break;
         case nsBoxFrame::vAlign_Bottom:
             aCurY = aBoxRect.y + aBoxRect.height - aCurrentChildSize.height;
             break;
      }
    }
  } else {
    // Handle alignment of a vertical box's children.
    if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
      aNextY = aCurY + aCurrentChildSize.height;
    else
      aNextY = aCurY - aCurrentChildSize.height;

    if (frameState & NS_STATE_AUTO_STRETCH)
      aCurX = aBoxRect.x;
    else {
      PRUint8 frameDirection = GetFrameDirection(aBox);
      switch (halign) 
      {
         case nsBoxFrame::hAlign_Left:
           if (frameDirection == NS_STYLE_DIRECTION_LTR)
             aCurX = aBoxRect.x;
           else
             aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width;
           break;
         case nsBoxFrame::hAlign_Center:
             aCurX = aBoxRect.x + (aBoxRect.width/2 - aCurrentChildSize.width/2);
             break;
         case nsBoxFrame::hAlign_Right:
           if (frameDirection == NS_STYLE_DIRECTION_LTR)
             aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width;
           else
             aCurX = aBoxRect.x;
           break;
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHOD nsIGridPart::CountRowsColumns ( nsIBox *  aBox,
PRInt32 aRowCount,
PRInt32 aComputedColumnCount 
) [pure virtual, inherited]
NS_IMETHOD nsIGridPart::DirtyRows ( nsIBox *  aBox,
nsBoxLayoutState aState 
) [pure virtual, inherited]
NS_IMETHODIMP nsSprocketLayout::GetAscent ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
nscoord aAscent 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Definition at line 1565 of file nsSprocketLayout.cpp.

{

  PRBool isHorizontal = IsHorizontal(aBox);

   aAscent = 0;

   // run through all the children and get there min, max, and preferred sizes
   // return us the size of the box
   
   nsIBox* child = nsnull;
   aBox->GetChildBox(&child);
   
   while (child) 
   {  
      // ignore collapsed children
      //PRBool isCollapsed = PR_FALSE;
      //aBox->IsCollapsed(aState, isCollapsed);

      //if (!isCollapsed)
      //{
        // if completely redefined don't even ask our child for its size.
        nscoord ascent = 0;
        child->GetAscent(aState, ascent);

        nsMargin margin;
        child->GetMargin(margin);
        ascent += margin.top;

        if (isHorizontal)
        {
          if (ascent > aAscent)
            aAscent = ascent;
        } else {
          if (aAscent == 0)
            aAscent = ascent;
        }
      //}
      child->GetNextBox(&child);
      
   }

  return NS_OK;
}

Here is the call graph for this function:

PRBool nsSprocketLayout::GetDefaultFlex ( PRInt32 aFlex) [protected, virtual, inherited]

Definition at line 1684 of file nsSprocketLayout.cpp.

{
    aFlex = 0;
    return PR_TRUE;
}
NS_IMETHODIMP nsSprocketLayout::GetFlex ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
nscoord aFlex 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Definition at line 1611 of file nsSprocketLayout.cpp.

{
  return aBox->GetFlex(aState, aFlex);
}
void nsSprocketLayout::GetFrameState ( nsIBox *  aBox,
nsFrameState aState 
) [protected, virtual, inherited]

Definition at line 99 of file nsSprocketLayout.cpp.

{
   aState = aBox->GetStateBits();
}

Here is the caller graph for this function:

NS_IMETHODIMP nsGridRowLayout::GetGrid ( nsIBox *  aBox,
nsGrid **  aList,
PRInt32 aIndex,
nsGridRowLayout aRequestor = nsnull 
) [virtual]

Implements nsIGridPart.

Definition at line 115 of file nsGridRowLayout.cpp.

{

   if (aRequestor == nsnull)
   {
      nsCOMPtr<nsIGridPart> parent;
      nsIBox* parentBox; // nsIBox is implemented by nsIFrame and is not refcounted.
      GetParentGridPart(aBox, &parentBox, getter_AddRefs(parent));
      if (parent)
         return parent->GetGrid(parentBox, aList, aIndex, this);
      else
         return NS_OK;
   }

   nsresult rv = NS_OK;

   PRInt32 index = -1;
   nsIBox* child = nsnull;
   aBox->GetChildBox(&child);
   PRInt32 count = 0;
   while(child)
   {
     // if there is a scrollframe walk inside it to its child
     nsIBox* childBox = nsGrid::GetScrolledBox(child);

     nsCOMPtr<nsIBoxLayout> layout;
     // childBox might be null if child is a scrollframe around a non-box.  But
     // in that case I guess we can count this as a single grid row.  Or
     // something.
     if (childBox) {
       childBox->GetLayoutManager(getter_AddRefs(layout));
     }
     
     // find our requester
     nsCOMPtr<nsIGridPart> gridRow = do_QueryInterface(layout, &rv);
     if (NS_SUCCEEDED(rv) && gridRow) 
     {
       if (layout == aRequestor) {
          index = count;
          break;
       }

       PRInt32 c = 0;
       gridRow->GetRowCount(c);
       count += c;
     } else 
       count++;

     child->GetNextBox(&child);
   }

   // if we didn't find ourselves then the tree isn't properly formed yet
   // this could happen during initial construction so lets just
   // fail.
   if (index == -1) {
     *aList = nsnull;
     *aIndex = -1;
     return NS_OK;
   }

   (*aIndex) += index;

   nsCOMPtr<nsIGridPart> parent;
   nsIBox* parentBox; // nsIBox is implemented by nsIFrame and is not refcounted.
   GetParentGridPart(aBox, &parentBox, getter_AddRefs(parent));

   if (parent)
      parent->GetGrid(parentBox, aList, aIndex, this);

   return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP nsSprocketLayout::GetMaxSize ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
nsSize aSize 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Reimplemented in nsGridRowGroupLayout, nsGridRowLeafLayout, and nsListBoxLayout.

Definition at line 1487 of file nsSprocketLayout.cpp.

{

  PRBool isHorizontal = IsHorizontal(aBox);

   nscoord smallestMax = NS_INTRINSICSIZE;

   aSize.width = NS_INTRINSICSIZE;
   aSize.height = NS_INTRINSICSIZE;

   // run through all the children and get there min, max, and preferred sizes
   // return us the size of the box


   nsIBox* child = nsnull;
   aBox->GetChildBox(&child);
   nsFrameState frameState = 0;
   GetFrameState(aBox, frameState);
   PRBool isEqual = frameState & NS_STATE_EQUAL_SIZE;
   PRInt32 count = 0;

   while (child) 
   {  
      // ignore collapsed children
      PRBool isCollapsed = PR_FALSE;
      aBox->IsCollapsed(aState, isCollapsed);

      if (!isCollapsed)
      {
        // if completely redefined don't even ask our child for its size.
        nsSize max(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
        nsSize min(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
        child->GetMaxSize(aState, max);
        child->GetMinSize(aState, min);
        nsBox::BoundsCheckMinMax(min, max);

        AddMargin(child, max);
        AddSmallestSize(aSize, max, isHorizontal);

        if (isEqual) {
          if (isHorizontal)
          {
            if (max.width < smallestMax)
              smallestMax = max.width;
          } else {
            if (max.height < smallestMax)
              smallestMax = max.height;
          }
        }
        count++;
      }

      child->GetNextBox(&child);  
   }

   if (isEqual) {
     if (isHorizontal) {
         if (smallestMax != NS_INTRINSICSIZE)
            aSize.width = smallestMax*count;
         else
            aSize.width = NS_INTRINSICSIZE;
     } else {
         if (smallestMax != NS_INTRINSICSIZE)
            aSize.height = smallestMax*count;
         else
            aSize.height = NS_INTRINSICSIZE;
     }
   }

   // now add our border and padding and insets
   AddBorderAndPadding(aBox, aSize);
   AddInset(aBox, aSize);

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsSprocketLayout::GetMinSize ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
nsSize aSize 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Reimplemented in nsGridRowLeafLayout, nsGridRowGroupLayout, and nsListBoxLayout.

Definition at line 1408 of file nsSprocketLayout.cpp.

{
   PRBool isHorizontal = IsHorizontal(aBox);

   nscoord biggestMin = 0;

   aSize.width = 0;
   aSize.height = 0;

   // run through all the children and get there min, max, and preferred sizes
   // return us the size of the box

   nsIBox* child = nsnull;
   aBox->GetChildBox(&child);
   nsFrameState frameState = 0;
   GetFrameState(aBox, frameState);
   PRBool isEqual = frameState & NS_STATE_EQUAL_SIZE;
   PRInt32 count = 0;

   while (child) 
   {  
       // ignore collapsed children
      PRBool isCollapsed = PR_FALSE;
      aBox->IsCollapsed(aState, isCollapsed);

      if (!isCollapsed)
      {
        nsSize min(0,0);
        nsSize pref(0,0);
        nscoord flex = 0;

        child->GetMinSize(aState, min);        
        child->GetFlex(aState, flex);
        
        // if the child is not flexible then
        // its min size is its pref size.
        if (flex == 0)  {
            child->GetPrefSize(aState, pref);
            if (isHorizontal)
               min.width = pref.width;
            else
               min.height = pref.height;
        }

        if (isEqual) {
          if (isHorizontal)
          {
            if (min.width > biggestMin)
              biggestMin = min.width;
          } else {
            if (min.height > biggestMin)
              biggestMin = min.height;
          }
        }

        AddMargin(child, min);
        AddLargestSize(aSize, min, isHorizontal);
        count++;
      }

      child->GetNextBox(&child);
   }

   
   if (isEqual) {
      if (isHorizontal)
         aSize.width = biggestMin*count;
      else
         aSize.height = biggestMin*count;
   }

// now add our border and padding and insets
   AddBorderAndPadding(aBox, aSize);
   AddInset(aBox,aSize);

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsGridRowLayout::GetParentGridPart ( nsIBox *  aBox,
nsIBox **  aParentBox,
nsIGridPart **  aParentGridRow 
) [virtual]

Implements nsIGridPart.

Definition at line 81 of file nsGridRowLayout.cpp.

{
  // go up and find our parent gridRow. Skip and non gridRow
  // parents.
  nsCOMPtr<nsIBoxLayout> layout;
  nsCOMPtr<nsIGridPart> parentGridRow;
  nsresult rv = NS_OK;
  *aParentGridPart = nsnull;
  
  // walk up through any scrollboxes
  aBox = nsGrid::GetScrollBox(aBox);

  // get the parent
  if (aBox)
      aBox->GetParentBox(&aBox);

  if (aBox)
  {
      aBox->GetLayoutManager(getter_AddRefs(layout));
      parentGridRow = do_QueryInterface(layout);
      *aParentGridPart = parentGridRow.get();
      *aParentBox = aBox;
      NS_IF_ADDREF(*aParentGridPart);
      return NS_OK;
  }

  *aParentGridPart = nsnull;
  *aParentBox = nsnull;
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsBoxLayout::GetParentLayout ( nsIBox *  aBox,
nsIBoxLayout **  aParent 
) [virtual, inherited]

Definition at line 62 of file nsBoxLayout.cpp.

{
  nsIBox* parent = nsnull;
  aBox->GetParentBox(&parent);
  if (parent)
  {
    parent->GetLayoutManager(aParent);
    return;
  }

  *aParent = nsnull;
}
NS_IMETHODIMP nsSprocketLayout::GetPrefSize ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
nsSize aSize 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Reimplemented in nsGridRowGroupLayout, nsGridRowLeafLayout, and nsListBoxLayout.

Definition at line 1343 of file nsSprocketLayout.cpp.

{
   PRBool isHorizontal = IsHorizontal(aBox);

   nscoord biggestPref = 0;

   aSize.width = 0;
   aSize.height = 0;

   // run through all the children and get there min, max, and preferred sizes
   // return us the size of the box

   nsIBox* child = nsnull;
   aBox->GetChildBox(&child);

   nsFrameState frameState = 0;
   GetFrameState(aBox, frameState);
   PRBool isEqual = frameState & NS_STATE_EQUAL_SIZE;
   PRInt32 count = 0;
   
   while (child) 
   {  
      // ignore collapsed children
      PRBool isCollapsed = PR_FALSE;
      child->IsCollapsed(aState, isCollapsed);

      if (!isCollapsed)
      {
        nsSize pref(0,0);
        child->GetPrefSize(aState, pref);
        AddMargin(child, pref);

        if (isEqual) {
          if (isHorizontal)
          {
            if (pref.width > biggestPref)
              biggestPref = pref.width;
          } else {
            if (pref.height > biggestPref)
              biggestPref = pref.height;
          }
        }

        AddLargestSize(aSize, pref, isHorizontal);
        count++;
      }

      child->GetNextBox(&child);
   }

   if (isEqual) {
      if (isHorizontal)
         aSize.width = biggestPref*count;
      else
         aSize.height = biggestPref*count;
   }
    
   // now add our border and padding and insets
   AddBorderAndPadding(aBox, aSize);
   AddInset(aBox, aSize);

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHOD nsIGridPart::GetRowCount ( PRInt32 aRowCount) [pure virtual, inherited]
NS_IMETHODIMP nsGridRowLayout::GetTotalMargin ( nsIBox *  aBox,
nsMargin aMargin,
PRBool  aIsHorizontal 
) [virtual]

Implements nsIGridPart.

Reimplemented in nsGridRowGroupLayout.

Definition at line 202 of file nsGridRowLayout.cpp.

{
  // get our parents margin
  nsMargin margin(0,0,0,0);
  nsCOMPtr<nsIGridPart> part;
  nsIBox* parent = nsnull;
  GetParentGridPart(aBox, &parent, getter_AddRefs(part));

  if (part && parent) {
    // if we are the first or last child walk upward and add margins.

    nsIBox* next = nsnull;
    nsIBox* child = nsnull;

    // make sure we check for a scrollbox
    aBox = nsGrid::GetScrollBox(aBox);

    // see if we have a next to see if we are last
    aBox->GetNextBox(&next);

    // get the parent first child to see if we are first
    parent->GetChildBox(&child);

    part->GetTotalMargin(parent,margin,aIsHorizontal);

    // if first or last
    if (child == aBox || next == nsnull) {

       // if its not the first child remove the top margin
       // we don't need it.
       if (child != aBox)
       {
          if (aIsHorizontal)
              margin.top = 0;
          else 
              margin.left = 0;
       }

       // if its not the last child remove the bottom margin
       // we don't need it.
       if (next != nsnull)
       {
          if (aIsHorizontal)
              margin.bottom = 0;
          else 
              margin.right = 0;
       }

    }
  }
    
  aMargin = margin;

  // add ours to it.
  aBox->GetMargin(margin);
  aMargin += margin;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsSprocketLayout::InvalidateComputedSizes ( nsComputedBoxSize aComputedBoxSizes) [protected, virtual, inherited]

Definition at line 1181 of file nsSprocketLayout.cpp.

{
  while(aComputedBoxSizes) {
      aComputedBoxSizes->valid = PR_FALSE;
      aComputedBoxSizes = aComputedBoxSizes->next;
  }
}

Here is the caller graph for this function:

NS_IMETHODIMP nsSprocketLayout::IsCollapsed ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
PRBool aCollapsed 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Definition at line 1618 of file nsSprocketLayout.cpp.

{
  return aBox->IsCollapsed(aState, aIsCollapsed);
}
PRBool nsSprocketLayout::IsHorizontal ( nsIBox *  aBox) [static, inherited]

Definition at line 93 of file nsSprocketLayout.cpp.

{
   return (aBox->GetStateBits() & NS_STATE_IS_HORIZONTAL) != 0;
}

Here is the caller graph for this function:

NS_IMETHODIMP nsSprocketLayout::Layout ( nsIBox *  aBox,
nsBoxLayoutState aState 
) [virtual, inherited]

Reimplemented from nsBoxLayout.

Reimplemented in nsGridRowLeafLayout, and nsListBoxLayout.

Definition at line 209 of file nsSprocketLayout.cpp.

{
  // See if we are collapsed. If we are, then simply iterate over all our
  // children and give them a rect of 0 width and height.
  PRBool collapsed = PR_FALSE;
  aBox->IsCollapsed(aState, collapsed);
  if (collapsed) {
    nsIBox* child;
    aBox->GetChildBox(&child);
    while(child) 
    {
      nsBoxFrame::LayoutChildAt(aState, child, nsRect(0,0,0,0));  
      child->GetNextBox(&child);
    }
    return NS_OK;
  }

  aState.PushStackMemory();

  // ----- figure out our size ----------
  nsRect contentRect;
  aBox->GetContentRect(contentRect);

  // -- make sure we remove our border and padding  ----
  nsRect clientRect;
  aBox->GetClientRect(clientRect);

  // |originalClientRect| represents the rect of the entire box (excluding borders
  // and padding).  We store it here because we're going to use |clientRect| to hold
  // the required size for all our kids.  As an example, consider an hbox with a
  // specified width of 300.  If the kids total only 150 pixels of width, then
  // we have 150 pixels left over.  |clientRect| is going to hold a width of 150 and
  // is going to be adjusted based off the value of the PACK property.  If flexible
  // objects are in the box, then the two rects will match.
  nsRect originalClientRect(clientRect);

  // The frame state contains cached knowledge about our box, such as our orientation
  // and direction.
  nsFrameState frameState = 0;
  GetFrameState(aBox, frameState);

  // Build a list of our children's desired sizes and computed sizes
  nsBoxSize*         boxSizes = nsnull;
  nsComputedBoxSize* computedBoxSizes = nsnull;

  nscoord maxAscent = 0;
  aBox->GetAscent(aState, maxAscent);

  nscoord min = 0;
  nscoord max = 0;
  PRInt32 flexes = 0;
  PopulateBoxSizes(aBox, aState, boxSizes, computedBoxSizes, min, max, flexes);
  
  // The |size| variable will hold the total size of children along the axis of
  // the box.  Continuing with the example begun in the comment above, size would
  // be 150 pixels.
  nscoord size = clientRect.width;
  if (!IsHorizontal(aBox))
    size = clientRect.height;
  ComputeChildSizes(aBox, aState, size, boxSizes, computedBoxSizes);

  // After the call to ComputeChildSizes, the |size| variable contains the
  // total required size of all the children.  We adjust our clientRect in the
  // appropriate dimension to match this size.  In our example, we now assign
  // 150 pixels into the clientRect.width.
  //
  // The variables |min| and |max| hold the minimum required size box must be 
  // in the OPPOSITE orientation, e.g., for a horizontal box, |min| is the minimum
  // height we require to enclose our children, and |max| is the maximum height
  // required to enclose our children.
  if (IsHorizontal(aBox)) {
    clientRect.width = size;
    if (clientRect.height < min)
      clientRect.height = min;

    if (frameState & NS_STATE_AUTO_STRETCH) {
      if (clientRect.height > max)
        clientRect.height = max;
    }
  } else {
    clientRect.height = size;
    if (clientRect.width < min)
      clientRect.width = min;

    if (frameState & NS_STATE_AUTO_STRETCH) {
      if (clientRect.width > max)
        clientRect.width = max;
    }
  }

  // With the sizes computed, now it's time to lay out our children.
  PRBool needsRedraw = PR_FALSE;
  PRBool finished;
  nscoord passes = 0;

  // We flow children at their preferred locations (along with the appropriate computed flex).  
  // After we flow a child, it is possible that the child will change its size.  If/when this happens,
  // we have to do another pass.  Typically only 2 passes are required, but the code is prepared to
  // do as many passes as are necessary to achieve equilibrium.
  nscoord x = 0;
  nscoord y = 0;
  nscoord origX = 0;
  nscoord origY = 0;

  // |childResized| lets us know if a child changed its size after we attempted to lay it out at
  // the specified size.  If this happens, we usually have to do another pass.
  PRBool childResized = PR_FALSE;

  // |passes| stores our number of passes.  If for any reason we end up doing more than, say, 10
  // passes, we assert to indicate that something is seriously screwed up.
  passes = 0;
  do 
  { 
#ifdef DEBUG_REFLOW
    if (passes > 0) {
      AddIndents();
      printf("ChildResized doing pass: %d\n", passes);
    }
#endif 

    // Always assume that we're done.  This will change if, for example, children don't stay
    // the same size after being flowed.
    finished = PR_TRUE;

    // Handle box packing.
    HandleBoxPack(aBox, frameState, x, y, originalClientRect, clientRect);

    // Now that packing is taken care of we set up a few additional
    // tracking variables.
    origX = x;
    origY = y;

    nscoord nextX = x;
    nscoord nextY = y;

    // Now we iterate over our box children and our box size lists in 
    // parallel.  For each child, we look at its sizes and figure out
    // where to place it.
    nsComputedBoxSize* childComputedBoxSize = computedBoxSizes;
    nsBoxSize* childBoxSize                 = boxSizes;

    nsIBox* child = nsnull;
    aBox->GetChildBox(&child);

    PRInt32 count = 0;
    while (child || (childBoxSize && childBoxSize->bogus))
    { 
      // If for some reason, our lists are not the same length, we guard
      // by bailing out of the loop.
      if (childBoxSize == nsnull) {
        NS_NOTREACHED("Lists not the same length.");
        break;
      }
        
      nscoord width = clientRect.width;
      nscoord height = clientRect.height;

      nsSize prefSize(0,0);
      nsSize minSize(0,0);
      nsSize maxSize(0,0);
      
      if (!childBoxSize->bogus) {
        // We have a valid box size entry.  This entry already contains information about our
        // sizes along the axis of the box (e.g., widths in a horizontal box).  If our default
        // ALIGN is not stretch, however, then we also need to know the child's size along the
        // opposite axis.
        if (!(frameState & NS_STATE_AUTO_STRETCH)) {
           child->GetPrefSize(aState, prefSize);
           child->GetMinSize(aState, minSize);
           child->GetMaxSize(aState, maxSize);
           nsBox::BoundsCheck(minSize, prefSize, maxSize);
       
           AddMargin(child, prefSize);
           width = PR_MIN(prefSize.width, originalClientRect.width);
           height = PR_MIN(prefSize.height, originalClientRect.height);
        }
      }

      // Obtain the computed size along the axis of the box for this child from the computedBoxSize entry.  
      // We store the result in |width| for horizontal boxes and |height| for vertical boxes.
      if (frameState & NS_STATE_IS_HORIZONTAL)
        width = childComputedBoxSize->size;
      else
        height = childComputedBoxSize->size;
      
      // Adjust our x/y for the left/right spacing.
      if (frameState & NS_STATE_IS_HORIZONTAL) {
        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
          x += (childBoxSize->left);
        else
          x -= (childBoxSize->right);
      } else {
        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
          y += (childBoxSize->left);
        else
          y -= (childBoxSize->right);
      }

      nextX = x;
      nextY = y;

      // Now we build a child rect.
      nscoord rectX = x;
      nscoord rectY = y;
      if (!(frameState & NS_STATE_IS_DIRECTION_NORMAL)) {
        if (frameState & NS_STATE_IS_HORIZONTAL)
          rectX -= width;
        else
          rectY -= height;
      }

      // We now create an accurate child rect based off our computed size information.
      nsRect childRect(rectX, rectY, width, height);

      // Sanity check against our clientRect.  It is possible that a child specified
      // a size that is too large to fit.  If that happens, then we have to grow
      // our client rect.  Remember, clientRect is not the total rect of the enclosing
      // box.  It currently holds our perception of how big the children needed to
      // be.
      if (childRect.width > clientRect.width || childRect.height > clientRect.height) {
        if (childRect.width > clientRect.width)
          clientRect.width = childRect.width;

        if (childRect.height > clientRect.height)
          clientRect.height = childRect.height;
      }
    
      // |x|, |y|, |nextX|, and |nextY| are updated by this function call.  This call
      // also deals with box ALIGNMENT (when stretching is not turned on).
      ComputeChildsNextPosition(aBox, child, 
                                x, 
                                y, 
                                nextX, 
                                nextY, 
                                childRect, 
                                originalClientRect, 
                                childBoxSize->ascent,
                                maxAscent);

      // Now we update our nextX/Y along our axis and we update our x/y along the opposite
      // axis (since a non-stretching alignment could have caused an adjustment).
      if (frameState & NS_STATE_IS_HORIZONTAL) {
        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
          nextX += (childBoxSize->right);
        else
          nextX -= (childBoxSize->left);
        childRect.y = y;
      }
      else {
        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
          nextY += (childBoxSize->right);
        else 
          nextY -= (childBoxSize->left);
        childRect.x = x;
      }
      
      // If we encounter a completely bogus box size, we just leave this child completely
      // alone and continue through the loop to the next child.
      if (childBoxSize->bogus) 
      {
        childComputedBoxSize = childComputedBoxSize->next;
        childBoxSize = childBoxSize->next;
        count++;
        x = nextX;
        y = nextY;
        continue;
      }

      nsMargin margin(0,0,0,0);

      PRBool layout = PR_TRUE;

      // Deflate the rect of our child by its margin.
      child->GetMargin(margin);
      childRect.Deflate(margin);
      if (childRect.width < 0)
        childRect.width = 0;
      if (childRect.height < 0)
        childRect.height = 0;

      // Now we're trying to figure out if we have to lay out this child, i.e., to call
      // the child's Layout method.
      if (passes > 0) {
        layout = PR_FALSE;
      } else {
        // Always perform layout if we are dirty or have dirty children
        PRBool dirty = PR_FALSE;           
        PRBool dirtyChildren = PR_FALSE;           
        child->IsDirty(dirty);
        child->HasDirtyChildren(dirtyChildren);
        if (!(dirty || dirtyChildren) && aState.LayoutReason() != nsBoxLayoutState::Initial)
          layout = PR_FALSE;
      }

      // We computed a childRect.  Now we want to set the bounds of the child to be that rect.
      // If our old rect is different, then we know our size changed and we cache that fact
      // in the |sizeChanged| variable.
      nsRect oldRect(child->GetRect());
      PRBool sizeChanged = PR_FALSE;

      child->SetBounds(aState, childRect);
      sizeChanged = (childRect.width != oldRect.width || childRect.height != oldRect.height);

      PRBool possibleRedraw = PR_FALSE;

      if (sizeChanged) {
        // Our size is different.  Sanity check against our maximum allowed size to ensure
        // we didn't exceed it.
        child->GetMinSize(aState, minSize);
        child->GetMaxSize(aState, maxSize);
        nsBox::BoundsCheckMinMax(minSize, maxSize);

        // make sure the size is in our max size.
        if (childRect.width > maxSize.width)
          childRect.width = maxSize.width;

        if (childRect.height > maxSize.height)
          childRect.height = maxSize.height;
           
        // set it again
        child->SetBounds(aState, childRect);

        // Since the child changed size, we know a redraw is probably going to be required.
        possibleRedraw = PR_TRUE;
      }

      // if something moved then we might need to redraw
      if (oldRect.x != childRect.x || oldRect.y != childRect.y)
          possibleRedraw = PR_TRUE;

      // If we already determined that layout was required or if our size has changed, then
      // we make sure to call layout on the child, since its children may need to be shifted
      // around as a result of the size change.
      if (layout || sizeChanged)
        child->Layout(aState);
      
      // If the child was a block or inline (e.g., HTML) it may have changed its rect *during* layout. 
      // We have to check for this.
      nsRect newChildRect(child->GetRect());

      if (newChildRect != childRect) {
#ifdef DEBUG_GROW
        child->DumpBox(stdout);
        printf(" GREW from (%d,%d) -> (%d,%d)\n", childRect.width, childRect.height, newChildRect.width, newChildRect.height);
#endif
        newChildRect.Inflate(margin);
        childRect.Inflate(margin);

        // The child changed size during layout.  The ChildResized method handles this
        // scenario.
        ChildResized(aBox,
                     aState, 
                     child,
                     childBoxSize,
                     childComputedBoxSize,
                     boxSizes, 
                     computedBoxSizes, 
                     childRect,
                     newChildRect,
                     clientRect,
                     flexes,
                     finished);

        // We note that a child changed size, which means that another pass will be required.
        childResized = PR_TRUE;

        // Now that a child resized, it's entirely possible that OUR rect is too small.  Now we
        // ensure that |originalClientRect| is grown to accommodate the size of |clientRect|.
        if (clientRect.width > originalClientRect.width || clientRect.height > originalClientRect.height) {
          if (clientRect.width > originalClientRect.width)
            originalClientRect.width = clientRect.width;

          if (clientRect.height > originalClientRect.height)
            originalClientRect.height = clientRect.height;
        }

        if (!(frameState & NS_STATE_IS_DIRECTION_NORMAL)) {
          // Our childRect had its XMost() or YMost() (depending on our layout
          // direction), positioned at a certain point.  Ensure that the
          // newChildRect satisfies the same constraint.  Note that this is
          // just equivalent to adjusting the x/y by the difference in
          // width/height between childRect and newChildRect.  So we don't need
          // to reaccount for the left and right of the box layout state again.
          if (frameState & NS_STATE_IS_HORIZONTAL)
            newChildRect.x = childRect.XMost() - newChildRect.width;
          else
            newChildRect.y = childRect.YMost() - newChildRect.height;
        }

        // If the child resized then recompute its position.
        ComputeChildsNextPosition(aBox, child, 
                                  x, 
                                  y, 
                                  nextX, 
                                  nextY, 
                                  newChildRect, 
                                  originalClientRect, 
                                  childBoxSize->ascent,
                                  maxAscent);

        // Only update the variable in the opposite axis (since this is only here to deal with
        // a non-stretching ALIGNMENT)
        if (frameState & NS_STATE_IS_HORIZONTAL)
          newChildRect.y = y;
        else
          newChildRect.x = x;
         
        if (newChildRect.width >= margin.left + margin.right && newChildRect.height >= margin.top + margin.bottom) 
          newChildRect.Deflate(margin);

        if (childRect.width >= margin.left + margin.right && childRect.height >= margin.top + margin.bottom) 
          childRect.Deflate(margin);
            
        child->SetBounds(aState, newChildRect);

        // If we are the first box that changed size, then we don't need to do a second pass
        if (count == 0)
          finished = PR_TRUE;
      }

      // Now update our x/y finally.
      x = nextX;
      y = nextY;
     
      // If we get here and |possibleRedraw| is still set, then it's official.  We do need a repaint.
      if (possibleRedraw)
        needsRedraw = PR_TRUE;

      // Move to the next child.
      childComputedBoxSize = childComputedBoxSize->next;
      childBoxSize = childBoxSize->next;

      child->GetNextBox(&child);
      count++;
    }

    // Sanity-checking code to ensure we don't do an infinite # of passes.
    passes++;
    NS_ASSERTION(passes < 10, "A Box's child is constantly growing!!!!!");
    if (passes > 10)
      break;
  } while (PR_FALSE == finished);

  // Get rid of our size lists.
  while(boxSizes)
  {
    nsBoxSize* toDelete = boxSizes;
    boxSizes = boxSizes->next;
    delete toDelete;
  }

  while(computedBoxSizes)
  {
    nsComputedBoxSize* toDelete = computedBoxSizes;
    computedBoxSizes = computedBoxSizes->next;
    delete toDelete;
  }

  if (childResized) {
    // See if one of our children forced us to get bigger
    nsRect tmpClientRect(originalClientRect);
    nsMargin bp(0,0,0,0);
    aBox->GetBorderAndPadding(bp);
    tmpClientRect.Inflate(bp);
    aBox->GetInset(bp);
    tmpClientRect.Inflate(bp);

    if (tmpClientRect.width > contentRect.width || tmpClientRect.height > contentRect.height)
    {
      // if it did reset our bounds.
      nsRect bounds(aBox->GetRect());
      if (tmpClientRect.width > contentRect.width)
        bounds.width = tmpClientRect.width;

      if (tmpClientRect.height > contentRect.height)
        bounds.height = tmpClientRect.height;

      aBox->SetBounds(aState, bounds);
    }
  }

  // Because our size grew, we now have to readjust because of box packing.  Repack
  // in order to update our x and y to the correct values.
  HandleBoxPack(aBox, frameState, x, y, originalClientRect, clientRect);

  // Compare against our original x and y and only worry about adjusting the children if
  // we really did have to change the positions because of packing (typically for 'center'
  // or 'end' pack values).
  if (x != origX || y != origY) {
    nsIBox* child = nsnull;
    // reposition all our children
    aBox->GetChildBox(&child);

    while (child) 
    {
      nsRect childRect(child->GetRect());
      childRect.x += (x - origX);
      childRect.y += (y - origY);
      child->SetBounds(aState, childRect);
      child->GetNextBox(&child);
    }
  }

  // Now do our redraw.
  if (needsRedraw)
    aBox->Redraw(aState);

  aState.PopStackMemory();

  // That's it!  If you made it this far without having a nervous breakdown, 
  // congratulations!  Go get yourself a beer.
  return NS_OK;
}

Here is the call graph for this function:

void nsSprocketLayout::PopulateBoxSizes ( nsIBox *  aBox,
nsBoxLayoutState aBoxLayoutState,
nsBoxSize *&  aBoxSizes,
nsComputedBoxSize *&  aComputedBoxSizes,
nscoord aMinSize,
nscoord aMaxSize,
PRInt32 aFlexes 
) [protected, virtual, inherited]

Reimplemented in nsGridRowLeafLayout.

Definition at line 724 of file nsSprocketLayout.cpp.

{
  // used for the equal size flag
  nscoord biggestPrefWidth = 0;
  nscoord biggestMinWidth = 0;
  nscoord smallestMaxWidth = NS_INTRINSICSIZE;

  nsFrameState frameState = 0;
  GetFrameState(aBox, frameState);

  //if (frameState & NS_STATE_CURRENTLY_IN_DEBUG)
  //   printf("In debug\n");

  aMinSize = 0;
  aMaxSize = NS_INTRINSICSIZE;

  PRBool isHorizontal;

  if (IsHorizontal(aBox))
     isHorizontal = PR_TRUE;
  else
     isHorizontal = PR_FALSE;

  // this is a nice little optimization
  // it turns out that if we only have 1 flexable child
  // then it does not matter what its preferred size is
  // there is nothing to flex it relative. This is great
  // because we can avoid asking for a preferred size in this
  // case. Why is this good? Well you might have html inside it
  // and asking html for its preferred size is rather expensive.
  // so we can just optimize it out this way.

  // set flexes
  nsIBox* child = nsnull;
  aBox->GetChildBox(&child);

  aFlexes = 0;
  nsBoxSize* currentBox = nsnull;

#if 0
  nsBoxSize* start = aBoxSizes;
  
  while(child)
  {
    // ok if we started with a list move down the list
    // until we reach the end. Then start looking at childen.
    // This feature is used extensively for Grid.
    nscoord flex = 0;    

    if (!start) {
      if (!currentBox) {
        aBoxSizes      = new (aState) nsBoxSize();
        currentBox      = aBoxSizes;
      } else {
        currentBox->next      = new (aState) nsBoxSize();
        currentBox      = currentBox->next;
      }
    

      child->GetFlex(aState, flex);
      PRBool collapsed = PR_FALSE;    
      child->IsCollapsed(aState, collapsed);

      currentBox->flex = flex;
      currentBox->collapsed = collapsed;
    } else {
      flex = start->flex;
      start = start->next;
    }
    
    if (flex > 0) 
       aFlexes++;
   
    child->GetNextBox(&child);
  }
#endif

  // get pref, min, max
  aBox->GetChildBox(&child);
  currentBox = aBoxSizes;
  nsBoxSize* last = nsnull;

  nscoord maxFlex = 0;
  PRInt32 childCount = 0;

  while(child)
  {
    ++childCount;
    nsSize pref(0,0);
    nsSize min(0,0);
    nsSize max(NS_INTRINSICSIZE,NS_INTRINSICSIZE);
    nscoord ascent = 0;

    PRBool collapsed = PR_FALSE;    
    child->IsCollapsed(aState, collapsed);

    if (!collapsed) {
    // only one flexible child? Cool we will just make its preferred size
    // 0 then and not even have to ask for it.
    //if (flexes != 1)  {

      child->GetPrefSize(aState, pref);
      child->GetMinSize(aState, min);
      child->GetMaxSize(aState, max);
      child->GetAscent(aState, ascent);
      nsMargin margin;
      child->GetMargin(margin);
      ascent += margin.top;
    //}

      nsBox::BoundsCheck(min, pref, max);

      AddMargin(child, pref);
      AddMargin(child, min);
      AddMargin(child, max);
    }

    if (!currentBox) {
      // create one.
      currentBox = new (aState) nsBoxSize();
      if (!aBoxSizes) {
        aBoxSizes = currentBox;
        last = aBoxSizes;
      } else {
        last->next = currentBox;
        last = currentBox;
      }

      nscoord minWidth;
      nscoord maxWidth;
      nscoord prefWidth;

      // get sizes from child
      if (isHorizontal) {
          minWidth  = min.width;
          maxWidth  = max.width;
          prefWidth = pref.width;
      } else {
          minWidth = min.height;
          maxWidth = max.height;
          prefWidth = pref.height;
      }

      nscoord flex = 0;
      child->GetFlex(aState, flex);

      // set them if you collapsed you are not flexible.
      if (collapsed) {
        currentBox->flex = 0;
      }
      else {
        if (flex > maxFlex) {
          maxFlex = flex;
        }
        currentBox->flex = flex;
      }

      // we we specified all our children are equal size;
      if (frameState & NS_STATE_EQUAL_SIZE) {

        if (prefWidth > biggestPrefWidth) 
          biggestPrefWidth = prefWidth;

        if (minWidth > biggestMinWidth) 
          biggestMinWidth = minWidth;

        if (maxWidth < smallestMaxWidth) 
          smallestMaxWidth = maxWidth;
      } else { // not we can set our children right now.
        currentBox->pref    = prefWidth;
        currentBox->min     = minWidth;
        currentBox->max     = maxWidth;
      }

      NS_ASSERTION(minWidth <= prefWidth && prefWidth <= maxWidth,"Bad min, pref, max widths!");

    }

    if (!isHorizontal) {
      if (min.width > aMinSize)
        aMinSize = min.width;

      if (max.width < aMaxSize)
        aMaxSize = max.width;

    } else {
      if (min.height > aMinSize)
        aMinSize = min.height;

      if (max.height < aMaxSize)
        aMaxSize = max.height;
    }

    currentBox->ascent  = ascent;
    currentBox->collapsed = collapsed;
    aFlexes += currentBox->flex;

    child->GetNextBox(&child);

    last = currentBox;
    currentBox = currentBox->next;

  }

  if (childCount > 0) {
    nscoord maxAllowedFlex = nscoord_MAX / childCount;
  
    if (NS_UNLIKELY(maxFlex > maxAllowedFlex)) {
      // clamp all the flexes
      currentBox = aBoxSizes;
      while (currentBox) {
        currentBox->flex = PR_MIN(currentBox->flex, maxAllowedFlex);
        currentBox = currentBox->next;      
      }
    }
  }
#ifdef DEBUG
  else {
    NS_ASSERTION(maxFlex == 0, "How did that happen?");
  }
#endif

  // we we specified all our children are equal size;
  if (frameState & NS_STATE_EQUAL_SIZE) {
    currentBox = aBoxSizes;

    while(currentBox)
    {
      if (!currentBox->collapsed) {
        currentBox->pref = biggestPrefWidth;
        currentBox->min = biggestMinWidth;
        currentBox->max = smallestMaxWidth;
      } else {
        currentBox->pref = 0;
        currentBox->min = 0;
        currentBox->max = 0;
      }
      currentBox = currentBox->next;
    }
  }

}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsSprocketLayout::SetLargestSize ( nsSize aSize1,
const nsSize aSize2,
PRBool  aIsHorizontal 
) [static, inherited]

Definition at line 1624 of file nsSprocketLayout.cpp.

{
  if (aIsHorizontal)
  {
    if (aSize1.height < aSize2.height)
       aSize1.height = aSize2.height;
  } else {
    if (aSize1.width < aSize2.width)
       aSize1.width = aSize2.width;
  }
}

Here is the caller graph for this function:

void nsSprocketLayout::SetSmallestSize ( nsSize aSize1,
const nsSize aSize2,
PRBool  aIsHorizontal 
) [static, inherited]

Definition at line 1637 of file nsSprocketLayout.cpp.

{
  if (aIsHorizontal)
  {
    if (aSize1.height > aSize2.height)
       aSize1.height = aSize2.height;
  } else {
    if (aSize1.width > aSize2.width)
       aSize1.width = aSize2.width;

  }
}

Here is the caller graph for this function:

void nsSprocketLayout::Shutdown ( ) [static, inherited]

Definition at line 83 of file nsSprocketLayout.cpp.


Friends And Related Function Documentation

nsresult NS_NewSprocketLayout ( nsIPresShell aPresShell,
nsCOMPtr< nsIBoxLayout > &  aNewLayout 
) [friend, inherited]

Definition at line 71 of file nsSprocketLayout.cpp.

{
  if (!nsSprocketLayout::gInstance) {
    nsSprocketLayout::gInstance = new nsSprocketLayout();
    NS_IF_ADDREF(nsSprocketLayout::gInstance);
  }
  // we have not instance variables so just return our static one.
  aNewLayout = nsSprocketLayout::gInstance;
  return NS_OK;
} 

The documentation for this class was generated from the following files: