NS_IMETHODIMP nsBox::GetDebugBoxAt( const nsPoint& aPoint, nsIBox** aBox) { nsRect thisRect(nsPoint(0,0), GetSize()); if (!thisRect.Contains(aPoint)) return NS_ERROR_FAILURE; nsIBox* child = GetChildBox(); nsIBox* hit = nsnull; *aBox = nsnull; while (nsnull != child) { nsresult rv = child->GetDebugBoxAt(aPoint - child->GetOffsetTo(this), &hit); if (NS_SUCCEEDED(rv) && hit) { *aBox = hit; } child = child->GetNextBox(); } // found a child if (*aBox) { return NS_OK; } return NS_ERROR_FAILURE; }
nsresult nsBox::BeginLayout(nsBoxLayoutState& aState) { #ifdef DEBUG_LAYOUT nsBoxAddIndents(); printf("Layout: "); DumpBox(stdout); printf("\n"); gIndent++; #endif // mark ourselves as dirty so no child under us // can post an incremental layout. // XXXldb Is this still needed? mState |= NS_FRAME_HAS_DIRTY_CHILDREN; if (GetStateBits() & NS_FRAME_IS_DIRTY) { // If the parent is dirty, all the children are dirty (nsHTMLReflowState // does this too). nsIFrame* box; for (box = GetChildBox(); box; box = box->GetNextBox()) box->AddStateBits(NS_FRAME_IS_DIRTY); } #ifdef DEBUG_LAYOUT PropagateDebug(aState); #endif return NS_OK; }
/** * This is redefined because row groups have a funny property. If they are flexible * then their flex must be equal to the sum of their children's flexes. */ nscoord nsGridRowGroupFrame::GetFlex(nsBoxLayoutState& aState) { // if we are flexible out flexibility is determined by our columns. // so first get the our flex. If not 0 then our flex is the sum of // our columns flexes. if (!DoesNeedRecalc(mFlex)) return mFlex; if (nsBoxFrame::GetFlex(aState) == 0) return 0; // ok we are flexible add up our children nscoord totalFlex = 0; nsIFrame* child = GetChildBox(); while (child) { totalFlex += child->GetFlex(aState); child = child->GetNextBox(); } mFlex = totalFlex; return totalFlex; }
NS_IMETHODIMP nsDeckFrame::DoLayout(nsBoxLayoutState& aState) { // Make sure we tweak the state so it does not resize our children. // We will do that. PRUint32 oldFlags = aState.LayoutFlags(); aState.SetLayoutFlags(NS_FRAME_NO_SIZE_VIEW | NS_FRAME_NO_VISIBILITY); // do a normal layout nsresult rv = nsBoxFrame::DoLayout(aState); // run though each child. Hide all but the selected one nsIBox* box = GetChildBox(); nscoord count = 0; while (box) { // make collapsed children not show up if (count == mIndex) ShowBox(aState.PresContext(), box); else HideBox(aState.PresContext(), box); box = box->GetNextBox(); count++; } aState.SetLayoutFlags(oldFlags); return rv; }
nsIBox* nsGroupBoxFrame::GetCaptionBox(nsPresContext* aPresContext, nsRect& aCaptionRect) { // first child is our grouped area nsIBox* box = GetChildBox(); // no area fail. if (!box) return nsnull; // get the first child in the grouped area, that is the caption box = box->GetChildBox(); // nothing in the area? fail if (!box) return nsnull; // now get the caption itself. It is in the caption frame. nsIBox* child = box->GetChildBox(); if (child) { // convert to our coordinates. nsRect parentRect(box->GetRect()); aCaptionRect = child->GetRect(); aCaptionRect.x += parentRect.x; aCaptionRect.y += parentRect.y; } return child; }
NS_IMETHODIMP nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // if we are too small to have a thumb don't paint it. nsIBox* thumb = GetChildBox(); if (thumb) { nsRect thumbRect(thumb->GetRect()); nsMargin m; thumb->GetMargin(m); thumbRect.Inflate(m); nsRect crect; GetClientRect(crect); if (crect.width < thumbRect.width || crect.height < thumbRect.height) return NS_OK; } return nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); }
nsresult nsBox::SyncLayout(nsBoxLayoutState& aState) { /* PRBool collapsed = PR_FALSE; IsCollapsed(aState, collapsed); if (collapsed) { CollapseChild(aState, this, PR_TRUE); return NS_OK; } */ if (GetStateBits() & NS_FRAME_IS_DIRTY) Redraw(aState); RemoveStateBits(NS_FRAME_HAS_DIRTY_CHILDREN | NS_FRAME_IS_DIRTY | NS_FRAME_FIRST_REFLOW | NS_FRAME_IN_REFLOW); nsPresContext* presContext = aState.PresContext(); PRUint32 flags = 0; GetLayoutFlags(flags); PRUint32 stateFlags = aState.LayoutFlags(); flags |= stateFlags; nsRect rect(nsPoint(0, 0), GetSize()); if (ComputesOwnOverflowArea()) { rect = GetOverflowRect(); } else { if (!DoesClipChildren() && !IsCollapsed(aState)) { // See if our child frames caused us to overflow after being laid // out. If so, store the overflow area. This normally can't happen // in XUL, but it can happen with the CSS 'outline' property and // possibly with other exotic stuff (e.g. relatively positioned // frames in HTML inside XUL). nsIFrame* box = GetChildBox(); while (box) { nsRect bounds = box->GetOverflowRect() + box->GetPosition(); rect.UnionRect(rect, bounds); box = box->GetNextBox(); } } FinishAndStoreOverflow(&rect, GetSize()); } nsIView* view = GetView(); if (view) { // Make sure the frame's view is properly sized and positioned and has // things like opacity correct nsHTMLContainerFrame::SyncFrameViewAfterReflow( presContext, this, view, &rect, flags); } return NS_OK; }
NS_IMETHODIMP nsSliderFrame::DoLayout(nsBoxLayoutState& aState) { // get the thumb should be our only child nsIBox* thumbBox = GetChildBox(); if (!thumbBox) { SyncLayout(aState); return NS_OK; } EnsureOrient(); #ifdef DEBUG_LAYOUT if (mState & NS_STATE_DEBUG_WAS_SET) { if (mState & NS_STATE_SET_TO_DEBUG) SetDebug(aState, PR_TRUE); else SetDebug(aState, PR_FALSE); } #endif // get the content area inside our borders nsRect clientRect; GetClientRect(clientRect); // get the scrollbar nsIBox* scrollbarBox = GetScrollbar(); nsCOMPtr<nsIContent> scrollbar; scrollbar = GetContentOfBox(scrollbarBox); // get the thumb's pref size nsSize thumbSize = thumbBox->GetPrefSize(aState); if (IsHorizontal()) thumbSize.height = clientRect.height; else thumbSize.width = clientRect.width; PRInt32 curPos = GetCurrentPosition(scrollbar); PRInt32 minPos = GetMinPosition(scrollbar); PRInt32 maxPos = GetMaxPosition(scrollbar); PRInt32 pageIncrement = GetPageIncrement(scrollbar); maxPos = NS_MAX(minPos, maxPos); curPos = NS_MAX(minPos, NS_MIN(curPos, maxPos)); nscoord& availableLength = IsHorizontal() ? clientRect.width : clientRect.height; nscoord& thumbLength = IsHorizontal() ? thumbSize.width : thumbSize.height; if ((pageIncrement + maxPos - minPos) > 0 && thumbBox->GetFlex(aState) > 0) { float ratio = float(pageIncrement) / float(maxPos - minPos + pageIncrement); thumbLength = NS_MAX(thumbLength, NSToCoordRound(availableLength * ratio)); } // Round the thumb's length to device pixels. nsPresContext* presContext = PresContext(); thumbLength = presContext->DevPixelsToAppUnits( presContext->AppUnitsToDevPixels(thumbLength)); // mRatio translates the thumb position in app units to the value. mRatio = (minPos != maxPos) ? float(availableLength - thumbLength) / float(maxPos - minPos) : 1; // in reverse mode, curpos is reversed such that lower values are to the // right or bottom and increase leftwards or upwards. In this case, use the // offset from the end instead of the beginning. PRBool reverse = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir, nsGkAtoms::reverse, eCaseMatters); nscoord pos = reverse ? (maxPos - curPos) : (curPos - minPos); // set the thumb's coord to be the current pos * the ratio. nsRect thumbRect(clientRect.x, clientRect.y, thumbSize.width, thumbSize.height); PRInt32& thumbPos = (IsHorizontal() ? thumbRect.x : thumbRect.y); thumbPos += NSToCoordRound(pos * mRatio); nsRect oldThumbRect(thumbBox->GetRect()); LayoutChildAt(aState, thumbBox, thumbRect); SyncLayout(aState); // Redraw only if thumb changed size. if (oldThumbRect != thumbRect) Redraw(aState); return NS_OK; }