nsGrid* nsGridRowLayout::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor) { if (aRequestor == nullptr) { nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted. nsIGridPart* parent = GetParentGridPart(aBox, &parentBox); if (parent) return parent->GetGrid(parentBox, aIndex, this); return nullptr; } int32_t index = -1; nsIFrame* child = nsBox::GetChildXULBox(aBox); int32_t count = 0; while(child) { // if there is a scrollframe walk inside it to its child nsIFrame* childBox = nsGrid::GetScrolledBox(child); nsBoxLayout* layout = childBox->GetXULLayoutManager(); nsIGridPart* gridRow = nsGrid::GetPartFromBox(childBox); if (gridRow) { if (layout == aRequestor) { index = count; break; } count += gridRow->GetRowCount(); } else count++; child = nsBox::GetNextXULBox(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) { *aIndex = -1; return nullptr; } (*aIndex) += index; nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted. nsIGridPart* parent = GetParentGridPart(aBox, &parentBox); if (parent) return parent->GetGrid(parentBox, aIndex, this); return nullptr; }
nsMargin nsGridRowLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) { // get our parents margin nsMargin margin(0,0,0,0); nsIFrame* parent = nullptr; nsIGridPart* part = GetParentGridPart(aBox, &parent); if (part && parent) { // if we are the first or last child walk upward and add margins. // make sure we check for a scrollbox aBox = nsGrid::GetScrollBox(aBox); // see if we have a next to see if we are last nsIFrame* next = nsBox::GetNextXULBox(aBox); // get the parent first child to see if we are first nsIFrame* child = nsBox::GetChildXULBox(parent); margin = part->GetTotalMargin(parent, aIsHorizontal); // if first or last if (child == aBox || next == nullptr) { // if it's 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 it's not the last child remove the bottom margin // we don't need it. if (next != nullptr) { if (aIsHorizontal) margin.bottom = 0; else margin.right = 0; } } } // add ours to it. nsMargin ourMargin; aBox->GetXULMargin(ourMargin); margin += ourMargin; return margin; }
void nsGridRowLeafLayout::ComputeChildSizes(nsIBox* aBox, nsBoxLayoutState& aState, nscoord& aGivenSize, nsBoxSize* aBoxSizes, nsComputedBoxSize*& aComputedBoxSizes) { // see if we are in a scrollable frame. If we are then there could be scrollbars present // if so we need to subtract them out to make sure our columns line up. if (aBox) { PRBool isHorizontal = aBox->IsHorizontal(); // go up the parent chain looking for scrollframes nscoord diff = 0; nsIBox* parentBox; nsIGridPart* parent = GetParentGridPart(aBox, &parentBox); while (parentBox) { nsIBox* scrollbox = nsGrid::GetScrollBox(parentBox); nsIScrollableFrame *scrollable = do_QueryFrame(scrollbox); if (scrollable) { // Don't call GetActualScrollbarSizes here because it's not safe // to call that while we're reflowing the contents of the scrollframe, // which we are here. nsMargin scrollbarSizes = scrollable->GetDesiredScrollbarSizes(&aState); PRUint32 visible = scrollable->GetScrollbarVisibility(); if (isHorizontal && (visible & nsIScrollableFrame::VERTICAL)) { diff += scrollbarSizes.left + scrollbarSizes.right; } else if (!isHorizontal && (visible & nsIScrollableFrame::HORIZONTAL)) { diff += scrollbarSizes.top + scrollbarSizes.bottom; } } parent = GetParentGridPart(parentBox, &parentBox); } if (diff > 0) { aGivenSize += diff; nsSprocketLayout::ComputeChildSizes(aBox, aState, aGivenSize, aBoxSizes, aComputedBoxSizes); aGivenSize -= diff; nsComputedBoxSize* s = aComputedBoxSizes; nsComputedBoxSize* last = aComputedBoxSizes; while(s) { last = s; s = s->next; } if (last) last->size -= diff; return; } } nsSprocketLayout::ComputeChildSizes(aBox, aState, aGivenSize, aBoxSizes, aComputedBoxSizes); }