Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
nsGrid Class Reference

#include <nsGrid.h>

Collaboration diagram for nsGrid:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsGrid ()
 ~nsGrid ()
nsGridRowGetColumnAt (PRInt32 aIndex, PRBool aIsHorizontal=PR_TRUE)
nsGridRowGetRowAt (PRInt32 aIndex, PRBool aIsHorizontal=PR_TRUE)
nsGridCellGetCellAt (PRInt32 aX, PRInt32 aY)
void NeedsRebuild (nsBoxLayoutState &aBoxLayoutState)
void RebuildIfNeeded ()
 If we are marked for rebuild.
nsresult GetPrefRowSize (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nsSize &aSize, PRBool aIsHorizontal=PR_TRUE)
 These methods return the preferred, min, max sizes for a given row index.
nsresult GetMinRowSize (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nsSize &aSize, PRBool aIsHorizontal=PR_TRUE)
nsresult GetMaxRowSize (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nsSize &aSize, PRBool aIsHorizontal=PR_TRUE)
nsresult GetRowFlex (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nscoord &aSize, PRBool aIsHorizontal=PR_TRUE)
 This get the flexibilty of the row at aIndex.
nsresult GetPrefRowHeight (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nscoord &aHeight, PRBool aIsHorizontal=PR_TRUE)
 These methods return the preferred, min, max coord for a given row index if aIsHorizontal is PR_TRUE.
nsresult GetMinRowHeight (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nscoord &aHeight, PRBool aIsHorizontal=PR_TRUE)
nsresult GetMaxRowHeight (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, nscoord &aHeight, PRBool aIsHorizontal=PR_TRUE)
void GetRowOffsets (nsBoxLayoutState &aState, PRInt32 aIndex, nscoord &aTop, nscoord &aBottom, PRBool aIsHorizontal=PR_TRUE)
 A row can have a top and bottom offset.
void RowChildIsDirty (nsBoxLayoutState &aBoxLayoutState, PRInt32 aRowIndex, PRInt32 aColumnIndex, PRBool aIsHorizontal=PR_TRUE)
 This is called if a child in a row became dirty.
void RowIsDirty (nsBoxLayoutState &aBoxLayoutState, PRInt32 aIndex, PRBool aIsHorizontal=PR_TRUE)
 The row became dirty.
void RowAddedOrRemoved (nsBoxLayoutState &aBoxLayoutState, PRInt32 aIndex, PRBool aIsHorizontal=PR_TRUE)
 A row or columns at the given index had been added or removed.
void CellAddedOrRemoved (nsBoxLayoutState &aBoxLayoutState, PRInt32 aIndex, PRBool aIsHorizontal=PR_TRUE)
void DirtyRows (nsIBox *aRowBox, nsBoxLayoutState &aState)
 Run through the rows in the given box and mark them dirty so they will get recalculated and get a layout.
PRInt32 GetExtraColumnCount (PRBool aIsHorizontal=PR_TRUE)
PRInt32 GetExtraRowCount (PRBool aIsHorizontal=PR_TRUE)
void SetBox (nsIBox *aBox)
nsIBox * GetBox ()
nsIBox * GetRowBox ()
nsIBox * GetColumnBox ()
nsGridRowGetColumns ()
nsGridRowGetRows ()
PRInt32 GetRowCount (PRInt32 aIsHorizontal=PR_TRUE)
PRInt32 GetColumnCount (PRInt32 aIsHorizontal=PR_TRUE)
void GetFirstAndLastRow (nsBoxLayoutState &aState, PRInt32 &aFirstIndex, PRInt32 &aLastIndex, nsGridRow *&aFirstRow, nsGridRow *&aLastRow, PRBool aIsHorizontal)
 The first and last rows can be affected by <rows> tags with borders or margin gets first and last rows and their indexes.

Static Public Member Functions

static nsIBox * GetScrolledBox (nsIBox *aChild)
static nsIBox * GetScrollBox (nsIBox *aChild)

Private Member Functions

void GetPartFromBox (nsIBox *aBox, nsIGridPart **aPart)
void GetBoxTotalMargin (nsIBox *aBox, nsMargin &aMargin, PRBool aIsHorizontal=PR_TRUE)
void FreeMap ()
void FindRowsAndColumns (nsIBox **aRows, nsIBox **aColumns)
 finds the first <rows> and <columns> tags in the <grid> tag
void BuildRows (nsIBox *aBox, PRBool aSize, nsGridRow **aColumnsRows, PRBool aIsHorizontal=PR_TRUE)
 Given the number of rows create nsGridRow objects for them and full them out.
void BuildCellMap (PRInt32 aRows, PRInt32 aColumns, nsGridCell **aCells)
 Given the number of rows and columns.
void PopulateCellMap (nsGridRow *aRows, nsGridRow *aColumns, PRInt32 aRowCount, PRInt32 aColumnCount, PRBool aIsHorizontal=PR_TRUE)
 Run through all the cells in the rows and columns and populate then with 2 cells.
void CountRowsColumns (nsIBox *aBox, PRInt32 &aRowCount, PRInt32 &aComputedColumnCount)
 Count the number of rows and columns in the given box.
void SetLargestSize (nsSize &aSize, nscoord aHeight, PRBool aIsHorizontal=PR_TRUE)
void SetSmallestSize (nsSize &aSize, nscoord aHeight, PRBool aIsHorizontal=PR_TRUE)
PRBool IsGrid (nsIBox *aBox)

Private Attributes

nsIBox * mBox
nsGridRowmRows
nsGridRowmColumns
nsIBox * mRowBox
nsIBox * mColumnBox
PRBool mNeedsRebuild
PRInt32 mRowCount
PRInt32 mColumnCount
PRInt32 mExtraRowCount
PRInt32 mExtraColumnCount
nsGridCellmCellMap
PRBool mMarkingDirty

Detailed Description

Definition at line 55 of file nsGrid.h.


Constructor & Destructor Documentation

Definition at line 141 of file nsGrid.cpp.

Here is the call graph for this function:


Member Function Documentation

void nsGrid::BuildCellMap ( PRInt32  aRows,
PRInt32  aColumns,
nsGridCell **  aCells 
) [private]

Given the number of rows and columns.

Build a cellmap

Definition at line 417 of file nsGrid.cpp.

{
  PRInt32 size = aRows*aColumns;
  PRInt32 oldsize = mRowCount*mColumnCount;
  if (size == 0) {
    delete[] mCellMap;
    (*aCells) = nsnull;
  }
  else {
    if (size > oldsize) {
      delete[] mCellMap;
      (*aCells) = new nsGridCell[size];
    } else {
      // clear out cellmap
      for (PRInt32 i=0; i < oldsize; i++)
      {
        mCellMap[i].SetBoxInRow(nsnull);
        mCellMap[i].SetBoxInColumn(nsnull);
      }

      (*aCells) = mCellMap;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::BuildRows ( nsIBox *  aBox,
PRBool  aSize,
nsGridRow **  aColumnsRows,
PRBool  aIsHorizontal = PR_TRUE 
) [private]

Given the number of rows create nsGridRow objects for them and full them out.

Definition at line 355 of file nsGrid.cpp.

{
  // if no rows then return null
  if (aRowCount == 0) {

    // make sure we free up the memory.
    if (*aRows)
      delete[] (*aRows);

    *aRows = nsnull;
    return;
  }

  // create the array
  nsGridRow* row;
  
  // only create new rows if we have to. Reuse old rows.
  if (aIsHorizontal)
  { 
    if (aRowCount > mRowCount) {
       delete[] mRows;
       row = new nsGridRow[aRowCount];
    } else {
      for (PRInt32 i=0; i < mRowCount; i++)
        mRows[i].Init(nsnull, PR_FALSE);

      row = mRows;
    }
  } else {
    if (aRowCount > mColumnCount) {
       delete[] mColumns;
       row = new nsGridRow[aRowCount];
    } else {
       for (PRInt32 i=0; i < mColumnCount; i++)
         mColumns[i].Init(nsnull, PR_FALSE);

       row = mColumns;
    }
  }

  // populate it if we can. If not it will contain only dynamic columns
  if (aBox)
  {
    nsCOMPtr<nsIBoxLayout> layout;
    aBox->GetLayoutManager(getter_AddRefs(layout));
    if (layout) {
      nsCOMPtr<nsIGridPart> monument( do_QueryInterface(layout) );
      if (monument) {
         PRInt32 count;
         monument->BuildRows(aBox, row, &count);
      }
    }
  }

  *aRows = row;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::CellAddedOrRemoved ( nsBoxLayoutState aBoxLayoutState,
PRInt32  aIndex,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 1432 of file nsGrid.cpp.

{
  // TBD see if the cell will fit in our current row. If it will
  // just add it in. 
  // but for now rebuild everything.
  if (mMarkingDirty)
    return;

  NeedsRebuild(aState);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::CountRowsColumns ( nsIBox *  aRowBox,
PRInt32 aRowCount,
PRInt32 aComputedColumnCount 
) [private]

Count the number of rows and columns in the given box.

aRowCount well become the actual number rows defined in the xul. aComputedColumnCount will become the number of columns by counting the number of cells in each row.

Definition at line 336 of file nsGrid.cpp.

{
  // get the rowboxes layout manager. Then ask it to do the work for us
  if (aRowBox) {
    nsCOMPtr<nsIBoxLayout> layout;
    aRowBox->GetLayoutManager(getter_AddRefs(layout));
    if (layout) {
       nsCOMPtr<nsIGridPart> monument( do_QueryInterface(layout) );
       if (monument) 
          monument->CountRowsColumns(aRowBox, aRowCount, aComputedColumnCount);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::DirtyRows ( nsIBox *  aRowBox,
nsBoxLayoutState aState 
)

Run through the rows in the given box and mark them dirty so they will get recalculated and get a layout.

Definition at line 498 of file nsGrid.cpp.

{
  // make sure we prevent others from dirtying things.
  mMarkingDirty = PR_TRUE;

  // if the box is a grid part have it recursively hand it.
  if (aRowBox) {
    nsCOMPtr<nsIBoxLayout> layout;
    aRowBox->GetLayoutManager(getter_AddRefs(layout));
    if (layout) {
       nsCOMPtr<nsIGridPart> part( do_QueryInterface(layout) );
       if (part) 
          part->DirtyRows(aRowBox, aState);
    }
  }

  mMarkingDirty = PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::FindRowsAndColumns ( nsIBox **  aRows,
nsIBox **  aColumns 
) [private]

finds the first <rows> and <columns> tags in the <grid> tag

Definition at line 279 of file nsGrid.cpp.

{
  *aRows = nsnull;
  *aColumns = nsnull;

  // find the boxes that contain our rows and columns
  nsIBox* child = nsnull;
  // if we have <grid></grid> then mBox will be null (bug 125689)
  if (mBox)
    mBox->GetChildBox(&child);

  while(child)
  {
    nsIBox* oldBox = child;
    nsresult rv = NS_OK;
    nsCOMPtr<nsIScrollableFrame> scrollFrame = do_QueryInterface(child, &rv);
    if (scrollFrame) {
       nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame();
       NS_ASSERTION(scrolledFrame,"Error no scroll frame!!");
       if (NS_FAILED(CallQueryInterface(scrolledFrame, &child)))
         child = nsnull;
    }

    nsCOMPtr<nsIBoxLayout> layout;
    child->GetLayoutManager(getter_AddRefs(layout));

     nsCOMPtr<nsIGridPart> monument( do_QueryInterface(layout) );
     if (monument)
     {
       nsGridRowGroupLayout* rowGroup = nsnull;
       monument->CastToRowGroupLayout(&rowGroup);
       if (rowGroup) {
          PRBool isHorizontal = !nsSprocketLayout::IsHorizontal(child);
          if (isHorizontal)
            *aRows = child;
          else
            *aColumns = child;
         
          if (*aRows && *aColumns)
            return;
       }
     }

    if (scrollFrame) {
      child = oldBox;
    }

    child->GetNextBox(&child);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::FreeMap ( ) [private]

Definition at line 253 of file nsGrid.cpp.

Here is the caller graph for this function:

nsIBox* nsGrid::GetBox ( ) [inline]

Definition at line 91 of file nsGrid.h.

{ return mBox; }
void nsGrid::GetBoxTotalMargin ( nsIBox *  aBox,
nsMargin aMargin,
PRBool  aIsHorizontal = PR_TRUE 
) [private]

Definition at line 647 of file nsGrid.cpp.

{
  // walk the boxes parent chain getting the border/padding/margin of our parent rows
  
  // first get the layour manager
  nsCOMPtr<nsIGridPart> part;
  nsCOMPtr<nsIGridPart> parent;
  GetPartFromBox(aBox, getter_AddRefs(part));
  if (part)
    part->GetTotalMargin(aBox, aMargin, aIsHorizontal);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 552 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  NS_ASSERTION(aY < mRowCount && aY >= 0, "Index out of range");
  NS_ASSERTION(aX < mColumnCount && aX >= 0, "Index out of range");
  return &mCellMap[aY*mColumnCount+aX];
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsGridRow * nsGrid::GetColumnAt ( PRInt32  aIndex,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 532 of file nsGrid.cpp.

{
  return GetRowAt(aIndex, !aIsHorizontal);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIBox* nsGrid::GetColumnBox ( ) [inline]

Definition at line 93 of file nsGrid.h.

{ return mColumnBox; }

Here is the caller graph for this function:

Definition at line 1361 of file nsGrid.cpp.

{
  return GetRowCount(!aIsHorizontal);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 517 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  return mColumns;
}

Here is the call graph for this function:

Definition at line 562 of file nsGrid.cpp.

{
  return GetExtraRowCount(!aIsHorizontal);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 568 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  if (aIsHorizontal)
    return mExtraRowCount;
  else
    return mExtraColumnCount;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::GetFirstAndLastRow ( nsBoxLayoutState aState,
PRInt32 aFirstIndex,
PRInt32 aLastIndex,
nsGridRow *&  aFirstRow,
nsGridRow *&  aLastRow,
PRBool  aIsHorizontal 
)

The first and last rows can be affected by <rows> tags with borders or margin gets first and last rows and their indexes.

If it fails because there are no rows then: FirstRow is nsnull LastRow is nsnull aFirstIndex = -1 aLastIndex = -1

Definition at line 669 of file nsGrid.cpp.

{
  aFirstRow = nsnull;
  aLastRow = nsnull;
  aFirstIndex = -1;
  aLastIndex = -1;

  PRInt32 count = GetRowCount(aIsHorizontal);

  if (count == 0)
    return;


  // We could have collapsed columns either before or after our index.
  // they should not count. So if we are the 5th row and the first 4 are
  // collaped we become the first row. Or if we are the 9th row and
  // 10 up to the last row are collapsed we then become the last.

  // see if we are first
  PRInt32 i;
  for (i=0; i < count; i++)
  {
     nsGridRow* row = GetRowAt(i,aIsHorizontal);
     if (!row->IsCollapsed(aState)) {
       aFirstIndex = i;
       aFirstRow = row;
       break;
     }
  }

  // see if we are last
  for (i=count-1; i >= 0; i--)
  {
     nsGridRow* row = GetRowAt(i,aIsHorizontal);
     if (!row->IsCollapsed(aState)) {
       aLastIndex = i;
       aLastRow = row;
       break;
     }

  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetMaxRowHeight ( nsBoxLayoutState aBoxLayoutState,
PRInt32  aRowIndex,
nscoord aHeight,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 1099 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsCollapsed(aState))
  {
    aSize = 0;
    return NS_OK;
  }

  if (row->IsMaxSet()) 
  {
    aSize = row->mMax;
    return NS_OK;
  }

  nsIBox* box = row->mBox;

  // set in CSS?
  if (box) {
    nsSize cssSize;
    cssSize.width = -1;
    cssSize.height = -1;
    nsIBox::AddCSSMaxSize(aState, box, cssSize);
    
    row->mMax = GET_HEIGHT(cssSize, aIsHorizontal);

    // yep do nothing.
    if (row->mMax != -1)
    {
      aSize = row->mMax;
      return NS_OK;
    }
  }

  // get the offsets so they are cached.
  nscoord top;
  nscoord bottom;
  GetRowOffsets(aState, aIndex, top, bottom, aIsHorizontal);

  // is the row bogus? If so then just ask it for its size
  // it should not be affected by cells in the grid. 
  if (row->mIsBogus)
  {
     nsSize size(NS_INTRINSICSIZE,NS_INTRINSICSIZE);
     nsIBox* box = row->GetBox();
     if (box) {
       box->GetPrefSize(aState, size);
       nsBox::AddMargin(box, size);
       nsStackLayout::AddOffset(aState, box, size);
     }

     row->mMax = GET_HEIGHT(size, aIsHorizontal);
     aSize = row->mMax;

     return NS_OK;
  }

  nsSize size(NS_INTRINSICSIZE,NS_INTRINSICSIZE);

  nsGridCell* child;

  PRInt32 count = GetColumnCount(aIsHorizontal); 

  PRBool isCollapsed = PR_FALSE;

  for (PRInt32 i=0; i < count; i++)
  {  
    if (aIsHorizontal)
     child = GetCellAt(i,aIndex);
    else
     child = GetCellAt(aIndex,i);

    // ignore collapsed children
    child->IsCollapsed(aState, isCollapsed);

    if (!isCollapsed)
    {
      nsSize childSize(0,0);
      child->GetMaxSize(aState, childSize);
      nsSize min(0,0);
      child->GetMinSize(aState, min);
      nsBox::BoundsCheckMinMax(min, childSize);

      nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
    }
  }

  row->mMax = GET_HEIGHT(size, aIsHorizontal) + top + bottom;

  aSize = row->mMax;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetMaxRowSize ( nsBoxLayoutState aBoxLayoutState,
PRInt32  aRowIndex,
nsSize aSize,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 614 of file nsGrid.cpp.

{ 
  NS_ASSERTION(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal), "Row index out of range!");

  if (!(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal)))
    return NS_OK;

  nscoord height = 0;
  GetMaxRowHeight(aState, aRowIndex, height, aIsHorizontal);
  SetSmallestSize(aSize, height, aIsHorizontal);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetMinRowHeight ( nsBoxLayoutState aBoxLayoutState,
PRInt32  aRowIndex,
nscoord aHeight,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 1003 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsCollapsed(aState))
  {
    aSize = 0;
    return NS_OK;
  } 

  if (row->IsMinSet()) 
  {
    aSize = row->mMin;
    return NS_OK;
  }

  nsIBox* box = row->mBox;

  // set in CSS?
  if (box) {
    nsSize cssSize;
    cssSize.width = -1;
    cssSize.height = -1;
    nsIBox::AddCSSMinSize(aState, box, cssSize);

    row->mMin = GET_HEIGHT(cssSize, aIsHorizontal);

    // yep do nothing.
    if (row->mMin != -1)
    {
      aSize = row->mMin;
      return NS_OK;
    }
  }

  // get the offsets so they are cached.
  nscoord top;
  nscoord bottom;
  GetRowOffsets(aState, aIndex, top, bottom, aIsHorizontal);

    // is the row bogus? If so then just ask it for its size
  // it should not be affected by cells in the grid. 
  if (row->mIsBogus)
  {
     nsSize size(0,0);
     nsIBox* box = row->GetBox();
     if (box) {
       box->GetPrefSize(aState, size);
       nsBox::AddMargin(box, size);
       nsStackLayout::AddOffset(aState, box, size);
     }

     row->mMin = GET_HEIGHT(size, aIsHorizontal) + top + bottom;
     aSize = row->mMin;

     return NS_OK;
  }

  nsSize size(0,0);

  nsGridCell* child;

  PRInt32 count = GetColumnCount(aIsHorizontal); 

  PRBool isCollapsed = PR_FALSE;

  for (PRInt32 i=0; i < count; i++)
  {  
    if (aIsHorizontal)
     child = GetCellAt(i,aIndex);
    else
     child = GetCellAt(aIndex,i);

    // ignore collapsed children
    child->IsCollapsed(aState, isCollapsed);

    if (!isCollapsed)
    {
      nsSize childSize(0,0);

      child->GetMinSize(aState, childSize);

      nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
    }
  }

  row->mMin = GET_HEIGHT(size, aIsHorizontal);

  aSize = row->mMin;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetMinRowSize ( nsBoxLayoutState aBoxLayoutState,
PRInt32  aRowIndex,
nsSize aSize,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 599 of file nsGrid.cpp.

{ 
  NS_ASSERTION(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal), "Row index out of range!");

  if (!(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal)))
    return NS_OK;

  nscoord height = 0;
  GetMinRowHeight(aState, aRowIndex, height, aIsHorizontal);
  SetLargestSize(aSize, height, aIsHorizontal);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::GetPartFromBox ( nsIBox *  aBox,
nsIGridPart **  aPart 
) [private]

Definition at line 629 of file nsGrid.cpp.

{
  *aPart = nsnull;

  if (aBox) {
    nsCOMPtr<nsIBoxLayout> layout;
    aBox->GetLayoutManager(getter_AddRefs(layout));
    if (layout) {
       nsCOMPtr<nsIGridPart> part( do_QueryInterface(layout) );
       if (part) { 
          *aPart = part.get();
          NS_IF_ADDREF(*aPart);
       }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetPrefRowHeight ( nsBoxLayoutState aState,
PRInt32  aIndex,
nscoord aSize,
PRBool  aIsHorizontal = PR_TRUE 
)

These methods return the preferred, min, max coord for a given row index if aIsHorizontal is PR_TRUE.

If you pass PR_FALSE you will get the inverse. As if you called GetPrefColumnHeight(aState, index, aPref).

Definition at line 903 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsCollapsed(aState))
  {
    aSize = 0;
    return NS_OK;
  }

  if (row->IsPrefSet()) 
  {
    aSize = row->mPref;
    return NS_OK;
  }

  nsIBox* box = row->mBox;

  // set in CSS?
  if (box) 
  {
    nsSize cssSize;
    cssSize.width = -1;
    cssSize.height = -1;
    nsIBox::AddCSSPrefSize(aState, box, cssSize);

    row->mPref = GET_HEIGHT(cssSize, aIsHorizontal);

    // yep do nothing.
    if (row->mPref != -1)
    {
      aSize = row->mPref;
      return NS_OK;
    }
  }

  // get the offsets so they are cached.
  nscoord top;
  nscoord bottom;
  GetRowOffsets(aState, aIndex, top, bottom, aIsHorizontal);


  // is the row bogus? If so then just ask it for its size
  // it should not be affected by cells in the grid. 
  if (row->mIsBogus)
  {
     nsSize size(0,0);
     nsIBox* box = row->GetBox();
     if (box) 
     {
       box->GetPrefSize(aState, size);
       nsBox::AddMargin(box, size);
       nsStackLayout::AddOffset(aState, box, size);
     }

     row->mPref = GET_HEIGHT(size, aIsHorizontal);
     aSize = row->mPref;

     return NS_OK;
  }

  nsSize size(0,0);

  nsGridCell* child;

  PRInt32 count = GetColumnCount(aIsHorizontal); 

  PRBool isCollapsed = PR_FALSE;

  for (PRInt32 i=0; i < count; i++)
  {  
    if (aIsHorizontal)
     child = GetCellAt(i,aIndex);
    else
     child = GetCellAt(aIndex,i);

    // ignore collapsed children
    child->IsCollapsed(aState, isCollapsed);

    if (!isCollapsed)
    {
      nsSize childSize(0,0);

      child->GetPrefSize(aState, childSize);

      nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
    }
  }

  row->mPref = GET_HEIGHT(size, aIsHorizontal) + top + bottom;


  aSize = row->mPref;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetPrefRowSize ( nsBoxLayoutState aState,
PRInt32  aRowIndex,
nsSize aSize,
PRBool  aIsHorizontal = PR_TRUE 
)

These methods return the preferred, min, max sizes for a given row index.

aIsHorizontal if aIsHorizontal is PR_TRUE. If you pass PR_FALSE you will get the inverse. As if you called GetPrefColumnSize(aState, index, aPref)

Definition at line 585 of file nsGrid.cpp.

{ 
  NS_ASSERTION(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal), "Row index out of range!");
  if (!(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal)))
    return NS_OK;

  nscoord height = 0;
  GetPrefRowHeight(aState, aRowIndex, height, aIsHorizontal);
  SetLargestSize(aSize, height, aIsHorizontal);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsGridRow * nsGrid::GetRowAt ( PRInt32  aIndex,
PRBool  aIsHorizontal = PR_TRUE 
)

Definition at line 538 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  if (aIsHorizontal) {
    NS_ASSERTION(aIndex < mRowCount && aIndex >= 0, "Index out of range");
    return &mRows[aIndex];
  } else {
    NS_ASSERTION(aIndex < mColumnCount && aIndex >= 0, "Index out of range");
    return &mColumns[aIndex];
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIBox* nsGrid::GetRowBox ( ) [inline]

Definition at line 92 of file nsGrid.h.

{ return mRowBox; }

Here is the caller graph for this function:

Definition at line 1350 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  if (aIsHorizontal)
    return mRowCount;
  else
    return mColumnCount;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsGrid::GetRowFlex ( nsBoxLayoutState aState,
PRInt32  aIndex,
nscoord aFlex,
PRBool  aIsHorizontal = PR_TRUE 
)

This get the flexibilty of the row at aIndex.

Its not trivial. There are a few things we need to look at. Specifically we need to see if any <rows> or <columns> tags are around us. Their flexibilty will affect ours.

Definition at line 1222 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsFlexSet()) 
  {
    aFlex = row->mFlex;
    return NS_OK;
  }

  nsIBox* box = row->mBox;
  row->mFlex = 0;

  if (box) {

    // We need our flex but a inflexible row could be around us. If so
    // neither are we. However if its the row tag just inside the grid it won't 
    // affect us. We need to do this for this case:
    // <grid> 
    //   <rows> 
    //     <rows> // this is not flexible. So our children should not be flexible
    //        <row flex="1"/>
    //        <row flex="1"/>
    //     </rows>
    //        <row/>
    //   </rows>
    // </grid>
    //
    // or..
    //
    // <grid> 
    //  <rows>
    //   <rows> // this is not flexible. So our children should not be flexible
    //     <rows flex="1"> 
    //        <row flex="1"/>
    //        <row flex="1"/>
    //     </rows>
    //        <row/>
    //   </rows>
    //  </row>
    // </grid>


    // So here is how it looks
    //
    // <grid>     
    //   <rows>   // parentsParent
    //     <rows> // parent
    //        <row flex="1"/> 
    //        <row flex="1"/>
    //     </rows>
    //        <row/>
    //   </rows>
    // </grid>

    // so the answer is simple: 1) Walk our parent chain. 2) If we find
    // someone who is not flexible and they aren't the rows immediately in
    // the grid. 3) Then we are not flexible

    nsIBox* parent=nsnull;
    nsIBox* parentsParent=nsnull;

    box = GetScrollBox(box);
    box->GetParentBox(&parent);
    
    while(parent)
    {
      parent = GetScrollBox(parent);
      parent->GetParentBox(&parentsParent);

      // if our parents parent is not a grid
      // the get its flex. If its 0 then we are
      // not flexible.
      if (parentsParent) {
        if (!IsGrid(parentsParent)) {
          PRInt32 flex = 0;
          parent->GetFlex(aState, flex);
          nsIBox::AddCSSFlex(aState, parent, flex);
          if (flex == 0) {
            row->mFlex = 0;
            aFlex = 0;
            return NS_OK;
          }
        } else 
          break;
      }

      parent = parentsParent;
    }
    
    // get the row flex.
    box->GetFlex(aState, row->mFlex);
    nsIBox::AddCSSFlex(aState, box, row->mFlex);

  }

  aFlex = row->mFlex;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::GetRowOffsets ( nsBoxLayoutState aState,
PRInt32  aIndex,
nscoord aTop,
nscoord aBottom,
PRBool  aIsHorizontal = PR_TRUE 
)

A row can have a top and bottom offset.

Usually this is just the top and bottom border/padding. However if the row is the first or last it could be affected by the fact a column or columns could have a top or bottom margin.

Definition at line 723 of file nsGrid.cpp.

{

  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsOffsetSet()) 
  {
    aTop    = row->mTop;
    aBottom = row->mBottom;
    return;
  }

  // first get the rows top and bottom border and padding
  nsIBox* box = row->GetBox();

  // add up all the padding
  nsMargin margin(0,0,0,0);
  nsMargin inset(0,0,0,0);
  nsMargin border(0,0,0,0);
  nsMargin padding(0,0,0,0);
  nsMargin totalBorderPadding(0,0,0,0);
  nsMargin totalMargin(0,0,0,0);

  // if there is a box and its not bogus take its
  // borders padding and insets into account
  if (box && !row->mIsBogus)
  {
     PRBool isCollapsed = PR_FALSE;
     box->IsCollapsed(aState, isCollapsed);

     if (!isCollapsed) 
     {

       box->GetInset(inset);

       // get real border and padding. GetBorderAndPadding
       // is redefined on nsGridRowLeafFrame. If we called it here
       // we would be in finite recurson.
       box->GetBorder(border);
       box->GetPadding(padding);

       totalBorderPadding += inset; 
       totalBorderPadding += border;
       totalBorderPadding += padding;

       box->GetMargin(margin);
     }

     // if we are the first or last row
     // take into account <rows> tags around us
     // that could have borders or margins.
     // fortunately they only affect the first
     // and last row inside the <rows> tag

     GetBoxTotalMargin(box, margin, aIsHorizontal);

     totalMargin = margin;
  }

  if (aIsHorizontal) {
    row->mTop = totalBorderPadding.top;
    row->mBottom = totalBorderPadding.bottom;
    row->mTopMargin = totalMargin.top;
    row->mBottomMargin = totalMargin.bottom;
  } else {
    row->mTop = totalBorderPadding.left;
    row->mBottom = totalBorderPadding.right;
    row->mTopMargin = totalMargin.left;
    row->mBottomMargin = totalMargin.right;
  }

  // if we are the first or last row take into account the top and bottom borders
  // of each columns. 

  // If we are the first row then get the largest top border/padding in 
  // our columns. If thats larger than the rows top border/padding use it.

  // If we are the last row then get the largest bottom border/padding in 
  // our columns. If thats larger than the rows bottom border/padding use it.
  PRInt32 firstIndex = 0;
  PRInt32 lastIndex = 0;
  nsGridRow* firstRow = nsnull;
  nsGridRow* lastRow = nsnull;
  GetFirstAndLastRow(aState, firstIndex, lastIndex, firstRow, lastRow, aIsHorizontal);

  if (aIndex == firstIndex || aIndex == lastIndex) {
    nscoord maxTop = 0;
    nscoord maxBottom = 0;

    // run through the columns. Look at each column
    // pick the largest top border or bottom border
    PRInt32 count = GetColumnCount(aIsHorizontal); 

    PRBool isCollapsed = PR_FALSE;

    for (PRInt32 i=0; i < count; i++)
    {  
      nsMargin totalChildBorderPadding(0,0,0,0);

      nsGridRow* column = GetColumnAt(i,aIsHorizontal);
      nsIBox* box = column->GetBox();

      if (box) 
      {
        // ignore collapsed children
        box->IsCollapsed(aState, isCollapsed);

        if (!isCollapsed)
        {
           // include the margin of the columns. To the row
           // at this point border/padding and margins all added
           // up to more needed space.
           GetBoxTotalMargin(box, margin, !aIsHorizontal);
           box->GetInset(inset);
           // get real border and padding. GetBorderAndPadding
           // is redefined on nsGridRowLeafFrame. If we called it here
           // we would be in finite recurson.
           box->GetBorder(border);
           box->GetPadding(padding);
           totalChildBorderPadding += inset; 
           totalChildBorderPadding += border;
           totalChildBorderPadding += padding;
           totalChildBorderPadding += margin;
        }

        nscoord top;
        nscoord bottom;

        // pick the largest top margin
        if (aIndex == firstIndex) {
          if (aIsHorizontal) {
            top = totalChildBorderPadding.top;
          } else {
            top = totalChildBorderPadding.left;
          }
          if (top > maxTop)
            maxTop = top;
        } 

        // pick the largest bottom margin
        if (aIndex == lastIndex) {
          if (aIsHorizontal) {
            bottom = totalChildBorderPadding.bottom;
          } else {
            bottom = totalChildBorderPadding.right;
          }
          if (bottom > maxBottom)
             maxBottom = bottom;
        }

      }
    
      // If the biggest top border/padding the columns is larger than this rows top border/padding
      // the use it.
      if (aIndex == firstIndex) {
        if (maxTop > (row->mTop + row->mTopMargin))
          row->mTop = maxTop - row->mTopMargin;
      }

      // If the biggest bottom border/padding the columns is larger than this rows bottom border/padding
      // the use it.
      if (aIndex == lastIndex) {
        if (maxBottom > (row->mBottom + row->mBottomMargin))
          row->mBottom = maxBottom - row->mBottomMargin;
      }
    }
  }
  
  aTop    = row->mTop;
  aBottom = row->mBottom;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 524 of file nsGrid.cpp.

{
  RebuildIfNeeded();

  return mRows;
}

Here is the call graph for this function:

nsIBox * nsGrid::GetScrollBox ( nsIBox *  aChild) [static]

Definition at line 1480 of file nsGrid.cpp.

{
  if (!aChild)
    return nsnull;

  // get parent
  nsIBox* parent = nsnull;
  nsCOMPtr<nsIBoxLayout> layout;
  nsCOMPtr<nsIGridPart> parentGridRow;

  aChild->GetParentBox(&parent);

  // walk up until we find a scrollframe or a part
  // if its a scrollframe return it.
  // if its a parent then the child passed does not
  // have a scroll frame immediately wrapped around it.
  while (parent) {
    nsCOMPtr<nsIScrollableFrame> scrollFrame = do_QueryInterface(parent);
    // scrollframe? Yep return it.
    if (scrollFrame)
      return parent;

    parent->GetLayoutManager(getter_AddRefs(layout));
    parentGridRow = do_QueryInterface(layout);
    // if a part then just return the child
    if (parentGridRow) 
      break;

    parent->GetParentBox(&parent);
  }

  return aChild;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIBox * nsGrid::GetScrolledBox ( nsIBox *  aChild) [static]

Definition at line 1462 of file nsGrid.cpp.

{
  // first see if it is a scrollframe. If so walk down into it and get the scrolled child
      nsCOMPtr<nsIScrollableFrame> scrollFrame = do_QueryInterface(aChild);
      if (scrollFrame) {
         nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame();
         NS_ASSERTION(scrolledFrame,"Error no scroll frame!!");
         return scrolledFrame->IsBoxFrame() ? scrolledFrame : nsnull;
      }

      return aChild;
}

Here is the call graph for this function:

PRBool nsGrid::IsGrid ( nsIBox *  aBox) [private]

Definition at line 1197 of file nsGrid.cpp.

{
  if (!aBox)
    return PR_FALSE;

  nsCOMPtr<nsIGridPart> part;
  GetPartFromBox(aBox, getter_AddRefs(part));
  if (!part)
    return PR_FALSE;

  nsGridLayout2* grid = nsnull; 
  part->CastToGridLayout(&grid);

  if (grid)
    return PR_TRUE;

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::NeedsRebuild ( nsBoxLayoutState aBoxLayoutState)

Definition at line 153 of file nsGrid.cpp.

{
  if (mNeedsRebuild)
    return;

  // iterate through columns and rows and dirty them
  mNeedsRebuild = PR_TRUE;

  // find the new row and column box. They could have 
  // been changed.
  mRowBox = nsnull;
  mColumnBox = nsnull;
  FindRowsAndColumns(&mRowBox, &mColumnBox);

  // tell all the rows and columns they are dirty
  DirtyRows(mRowBox, aState);
  DirtyRows(mColumnBox, aState);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::PopulateCellMap ( nsGridRow aRows,
nsGridRow aColumns,
PRInt32  aRowCount,
PRInt32  aColumnCount,
PRBool  aIsHorizontal = PR_TRUE 
) [private]

Run through all the cells in the rows and columns and populate then with 2 cells.

One from the row and one from the column

Definition at line 447 of file nsGrid.cpp.

{
  if (!aRows)
    return;

   // look through the columns
  nscoord j = 0;

  for(PRInt32 i=0; i < aRowCount; i++) 
  {
     nsIBox* child = nsnull;
     nsGridRow* row = &aRows[i];

     // skip bogus rows. They have no cells
     if (row->mIsBogus) 
       continue;

     child = row->mBox;
     if (child) {
       child->GetChildBox(&child);

       j = 0;

       while(child && j < aColumnCount)
       {
         // skip bogus column. They have no cells
         nsGridRow* column = &aColumns[j];
         if (column->mIsBogus) 
         {
           j++;
           continue;
         }

         if (aIsHorizontal)
           GetCellAt(j,i)->SetBoxInRow(child);
         else
           GetCellAt(i,j)->SetBoxInColumn(child);

         child->GetNextBox(&child);

         j++;
       }
     }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

If we are marked for rebuild.

Then build everything

Definition at line 178 of file nsGrid.cpp.

{
  if (!mNeedsRebuild)
    return;

  mNeedsRebuild = PR_FALSE;

  // find the row and columns frames
  FindRowsAndColumns(&mRowBox, &mColumnBox);

  // count the rows and columns
  PRInt32 computedRowCount = 0;
  PRInt32 computedColumnCount = 0;
  PRInt32 rowCount = 0;
  PRInt32 columnCount = 0;

  CountRowsColumns(mRowBox, rowCount, computedColumnCount);
  CountRowsColumns(mColumnBox, columnCount, computedRowCount);

  // computedRowCount are the actual number of rows as determined by the 
  // columns children.
  // computedColumnCount are the number of columns as determined by the number
  // of rows children.
  // We can use this information to see how many extra columns or rows we need.
  // This can happen if there are are more children in a row that number of columns
  // defined. Example:
  //
  // <columns>
  //   <column/>
  // </columns>
  //
  // <rows>
  //   <row>
  //     <button/><button/>
  //   </row>
  // </rows>
  //
  // computedColumnCount = 2 // for the 2 buttons in the the row tag
  // computedRowCount = 0 // there is nothing in the  column tag
  // mColumnCount = 1 // one column defined
  // mRowCount = 1 // one row defined
  // 
  // So in this case we need to make 1 extra column.
  //

  // Make sure to update mExtraColumnCount no matter what, since it might
  // happen that we now have as many columns as are defined, and we wouldn't
  // want to have a positive mExtraColumnCount hanging about in that case!
  mExtraColumnCount = computedColumnCount - columnCount;
  if (computedColumnCount > columnCount) {
     columnCount = computedColumnCount;
  }

  // Same for rows.
  mExtraRowCount = computedRowCount - rowCount;
  if (computedRowCount > rowCount) {
     rowCount = computedRowCount;
  }

  // build and poplulate row and columns arrays
  BuildRows(mRowBox, rowCount, &mRows, PR_TRUE);
  BuildRows(mColumnBox, columnCount, &mColumns, PR_FALSE);

  // build and populate the cell map
  BuildCellMap(rowCount, columnCount, &mCellMap);

  mRowCount = rowCount;
  mColumnCount = columnCount;

  // populate the cell map from column and row children
  PopulateCellMap(mRows, mColumns, mRowCount, mColumnCount, PR_TRUE);
  PopulateCellMap(mColumns, mRows, mColumnCount, mRowCount, PR_FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::RowAddedOrRemoved ( nsBoxLayoutState aBoxLayoutState,
PRInt32  aIndex,
PRBool  aIsHorizontal = PR_TRUE 
)

A row or columns at the given index had been added or removed.

Definition at line 1447 of file nsGrid.cpp.

{
  // TBD see if we have extra room in the table and just add the new row in
  // for now rebuild the world
  if (mMarkingDirty)
    return;

  NeedsRebuild(aState);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::RowChildIsDirty ( nsBoxLayoutState aState,
PRInt32  aRowIndex,
PRInt32  aColumnIndex,
PRBool  aIsHorizontal = PR_TRUE 
)

This is called if a child in a row became dirty.

This happens if the child gets bigger or smaller in some way.

Definition at line 1371 of file nsGrid.cpp.

{ 
  // if we are already dirty do nothing.
  if (mNeedsRebuild || mMarkingDirty)
    return;

  NeedsRebuild(aState);

  // This code does not work with trees when rows are
  // dynamically inserted, the cache values are invalid.
  /*
  mMarkingDirty = PR_TRUE;

  // index out of range. Rebuild it all
  if (aRowIndex >= GetRowCount(aIsHorizontal) || aColumnIndex >= GetColumnCount(aIsHorizontal))
  {
    NeedsRebuild(aState);
    return;
  }

  // dirty our 2 outer nsGridRows. (one for columns and one for rows)
  // we need to do this because the rows and column we are given may be Extra ones
  // and may not have any Box associated with them. If you dirtied them then
  // corresponding nsGridRowGroup around them would never get dirty. So lets just
  // do it manually here.

  if (mRowBox)
    mRowBox->MarkDirty(aState);

  if (mColumnBox)
    mColumnBox->MarkDirty(aState);

  // dirty just our row and column that we were given
  nsGridRow* row = GetRowAt(aRowIndex, aIsHorizontal);
  row->MarkDirty(aState);

  nsGridRow* column = GetColumnAt(aColumnIndex, aIsHorizontal);
  column->MarkDirty(aState);


  mMarkingDirty = PR_FALSE;
  */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::RowIsDirty ( nsBoxLayoutState aState,
PRInt32  aIndex,
PRBool  aIsHorizontal = PR_TRUE 
)

The row became dirty.

This happens if the row's borders change or children inside it force it to change size

Definition at line 1420 of file nsGrid.cpp.

{
  if (mMarkingDirty)
    return;

  NeedsRebuild(aState);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsGrid::SetBox ( nsIBox *  aBox) [inline]

Definition at line 90 of file nsGrid.h.

{ mBox = aBox; }

Here is the caller graph for this function:

void nsGrid::SetLargestSize ( nsSize aSize,
nscoord  aHeight,
PRBool  aIsHorizontal = PR_TRUE 
) [private]

Definition at line 1326 of file nsGrid.cpp.

{
  if (aIsHorizontal) {
    if (aSize.height < aHeight)
      aSize.height = aHeight;
  } else {
    if (aSize.width < aHeight)
      aSize.width = aHeight;
  }
}

Here is the caller graph for this function:

void nsGrid::SetSmallestSize ( nsSize aSize,
nscoord  aHeight,
PRBool  aIsHorizontal = PR_TRUE 
) [private]

Definition at line 1338 of file nsGrid.cpp.

{
  if (aIsHorizontal) {
    if (aSize.height > aHeight)
      aSize.height = aHeight;
  } else {
    if (aSize.width < aHeight)
      aSize.width = aHeight;
  }
}

Here is the caller graph for this function:


Member Data Documentation

nsIBox* nsGrid::mBox [private]

Definition at line 123 of file nsGrid.h.

Definition at line 150 of file nsGrid.h.

nsIBox* nsGrid::mColumnBox [private]

Definition at line 135 of file nsGrid.h.

Definition at line 142 of file nsGrid.h.

Definition at line 129 of file nsGrid.h.

Definition at line 147 of file nsGrid.h.

Definition at line 146 of file nsGrid.h.

Definition at line 154 of file nsGrid.h.

Definition at line 138 of file nsGrid.h.

nsIBox* nsGrid::mRowBox [private]

Definition at line 132 of file nsGrid.h.

Definition at line 141 of file nsGrid.h.

Definition at line 126 of file nsGrid.h.


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