Esempio n. 1
0
/**
 * 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
 */
void
nsGrid::GetFirstAndLastRow(nsBoxLayoutState& aState, 
                          PRInt32& aFirstIndex, 
                          PRInt32& aLastIndex, 
                          nsGridRow*& aFirstRow,
                          nsGridRow*& aLastRow,
                          bool aIsHorizontal)
{
  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;
     }

  }
}
Esempio n. 2
0
NS_IMETHODIMP
nsARIAGridAccessible::UnselectRow(PRInt32 aRow)
{
  if (IsDefunct())
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
  NS_ENSURE_ARG(row);

  return SetARIASelected(row, PR_FALSE);
}
Esempio n. 3
0
// Iterate over all valid rows in this batch
void RowBatch::Iterate(CodeGen &codegen, RowBatch::IterateCallback &cb) {
  // The starting position in the batch
  llvm::Value *start = codegen.Const32(0);

  // The ending position in the batch
  llvm::Value *end = GetNumValidRows(codegen);

  // Generating the loop
  std::vector<lang::Loop::LoopVariable> loop_vars = {
      {"readIdx", start}, {"writeIdx", codegen.Const32(0)}};
  llvm::Value *loop_cond = codegen->CreateICmpULT(start, end);
  lang::Loop batch_loop{codegen, loop_cond, loop_vars};
  {
    // Pull out loop vars for convenience
    auto *batch_pos = batch_loop.GetLoopVar(0);
    auto *write_pos = batch_loop.GetLoopVar(1);

    // Create an output tracker to track the final position of the row
    OutputTracker tracker{GetSelectionVector(), write_pos};

    // Get the current row
    RowBatch::Row row = GetRowAt(batch_pos, &tracker);

    // Invoke callback
    cb.ProcessRow(row);

    // The next read position is one next
    auto *next_read_pos = codegen->CreateAdd(batch_pos, codegen.Const32(1));

    // The write position from the output track
    auto *next_write_pos = tracker.GetFinalOutputPos();

    // Close up loop
    llvm::Value *loop_cond = codegen->CreateICmpULT(next_read_pos, end);
    batch_loop.LoopEnd(loop_cond, {next_read_pos, next_write_pos});
  }

  // After the batch loop, we need to reset the size of the selection vector
  std::vector<llvm::Value *> final_vals;
  batch_loop.CollectFinalLoopVariables(final_vals);

  // Mark the last position in the batch
  UpdateWritePosition(final_vals[1]);
}
Esempio n. 4
0
NS_IMETHODIMP
nsARIAGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                nsIAccessible **aAccessible)
{
  NS_ENSURE_ARG_POINTER(aAccessible);
  *aAccessible = nsnull;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIAccessible> row = GetRowAt(aRowIndex);
  NS_ENSURE_ARG(row);

  nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumnIndex);
  NS_ENSURE_ARG(cell);

  NS_ADDREF(*aAccessible = cell);
  return NS_OK;
}
Esempio n. 5
0
void
nsGrid::PrintCellMap()
{
  
  printf("-----Columns------\n");
  for (int x=0; x < mColumnCount; x++) 
  {
   
    nsGridRow* column = GetColumnAt(x);
    printf("%d(pf=%d, mn=%d, mx=%d) ", x, column->mPref, column->mMin, column->mMax);
  }

  printf("\n-----Rows------\n");
  for (x=0; x < mRowCount; x++) 
  {
    nsGridRow* column = GetRowAt(x);
    printf("%d(pf=%d, mn=%d, mx=%d) ", x, column->mPref, column->mMin, column->mMax);
  }

  printf("\n");
  
}
Esempio n. 6
0
NS_IMETHODIMP
nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
{
  NS_ENSURE_ARG_POINTER(aIsSelected);
  *aIsSelected = PR_FALSE;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
  NS_ENSURE_ARG(row);

  if (!nsAccUtils::IsARIASelected(row)) {
    nsCOMPtr<nsIAccessible> cell;
    while ((cell = GetNextCellInRow(row, cell))) {
      if (!nsAccUtils::IsARIASelected(cell))
        return NS_OK;
    }
  }

  *aIsSelected = PR_TRUE;
  return NS_OK;
}
Esempio n. 7
0
NS_IMETHODIMP
nsARIAGridAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
                                     PRBool *aIsSelected)
{
  NS_ENSURE_ARG_POINTER(aIsSelected);
  *aIsSelected = PR_FALSE;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIAccessible> row(GetRowAt(aRow));
  NS_ENSURE_ARG(row);

  if (!nsAccUtils::IsARIASelected(row)) {
    nsCOMPtr<nsIAccessible> cell(GetCellInRowAt(row, aColumn));
    NS_ENSURE_ARG(cell);

    if (!nsAccUtils::IsARIASelected(cell))
      return NS_OK;
  }

  *aIsSelected = PR_TRUE;
  return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
{
  NS_ENSURE_ARG_POINTER(aIsSelected);
  *aIsSelected = PR_FALSE;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  nsAccessible *row = GetRowAt(aRow);
  NS_ENSURE_ARG(row);

  if (!nsAccUtils::IsARIASelected(row)) {
    AccIterator cellIter(row, filters::GetCell);
    nsAccessible *cell = nsnull;
    while ((cell = cellIter.GetNext())) {
      if (!nsAccUtils::IsARIASelected(cell))
        return NS_OK;
    }
  }

  *aIsSelected = PR_TRUE;
  return NS_OK;
}
Esempio n. 9
0
nscoord
nsGrid::GetMaxRowHeight(nsBoxLayoutState& aState, PRInt32 aIndex, bool aIsHorizontal)
{
  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsCollapsed(aState))
    return 0;

  if (row->IsMaxSet()) 
    return row->mMax;

  nsIBox* box = row->mBox;

  // set in CSS?
  if (box) {
    bool widthSet, heightSet;
    nsSize cssSize(-1, -1);
    nsIBox::AddCSSMaxSize(box, cssSize, widthSet, heightSet);

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

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

  // 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);
     if (box) {
       size = box->GetPrefSize(aState);
       nsBox::AddMargin(box, size);
       nsGridLayout2::AddOffset(aState, box, size);
     }

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

  nsSize size(NS_INTRINSICSIZE,NS_INTRINSICSIZE);

  nsGridCell* child;

  PRInt32 count = GetColumnCount(aIsHorizontal); 

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

    // ignore collapsed children
    if (!child->IsCollapsed(aState))
    {
      nsSize min = child->GetMinSize(aState);
      nsSize childSize = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
      nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
    }
  }

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

  return row->mMax;
}
Esempio n. 10
0
/**
 * 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. 
 */
void
nsGrid::GetRowOffsets(nsBoxLayoutState& aState, PRInt32 aIndex, nscoord& aTop, nscoord& aBottom, bool aIsHorizontal)
{

  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 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 it's not bogus take its
  // borders padding into account
  if (box && !row->mIsBogus)
  {
    if (!box->IsCollapsed(aState))
    {
       // 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 += border;
       totalBorderPadding += padding;
     }

     // 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

     totalMargin = GetBoxTotalMargin(box, aIsHorizontal);
  }

  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 that's 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 that's 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); 

    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
        if (!box->IsCollapsed(aState))
        {
           // include the margin of the columns. To the row
           // at this point border/padding and margins all added
           // up to more needed space.
           margin = GetBoxTotalMargin(box, !aIsHorizontal);
           // 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 += 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;
}
Esempio n. 11
0
nsGridRow*
nsGrid::GetColumnAt(PRInt32 aIndex, bool aIsHorizontal)
{
  return GetRowAt(aIndex, !aIsHorizontal);
}
Esempio n. 12
0
/**
 * This get the flexibilty of the row at aIndex. It's 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.
 */
nscoord
nsGrid::GetRowFlex(nsBoxLayoutState& aState, PRInt32 aIndex, bool aIsHorizontal)
{
  RebuildIfNeeded();

  nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);

  if (row->IsFlexSet()) 
    return row->mFlex;

  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

    box = GetScrollBox(box);
    nsIBox* parent = box->GetParentBox();
    nsIBox* parentsParent=nsnull;

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

      // 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)) {
          nscoord flex = parent->GetFlex(aState);
          nsIBox::AddCSSFlex(aState, parent, flex);
          if (flex == 0) {
            row->mFlex = 0;
            return row->mFlex;
          }
        } else 
          break;
      }

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

  return row->mFlex;
}