Files
Mozilla/mozilla/layout/xul/base/src/nsStackLayout.cpp
evaughan%netscape.com 82b44e2844 box skinnablility changes.
-r Hyatt


git-svn-id: svn://10.0.0.236/trunk@64707 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-31 07:02:06 +00:00

267 lines
6.4 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
//
// Eric Vaughan
// Netscape Communications
//
// See documentation in associated header file
//
#include "nsStackLayout.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
#include "nsHTMLIIDs.h"
#include "nsUnitConversion.h"
#include "nsINameSpaceManager.h"
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsIReflowCommand.h"
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
#include "nsStyleChangeList.h"
#include "nsCSSRendering.h"
#include "nsIViewManager.h"
#include "nsBoxLayoutState.h"
#include "nsIBox.h"
nsStackLayout::nsStackLayout(nsIPresShell* aPresShell)
{
}
NS_IMETHODIMP
nsStackLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
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);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
child->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
nsSize pref(0,0);
child->GetPrefSize(aBoxLayoutState, pref);
AddMargin(child, pref);
AddLargestSize(aSize, pref);
}
child->GetNextBox(&child);
}
// now add our border and padding and insets
AddBorderAndPadding(aBox, aSize);
AddInset(aBox, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
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);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
aBox->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
nsSize min(0,0);
child->GetMinSize(aBoxLayoutState, min);
AddMargin(child, min);
AddLargestSize(aSize, min);
}
child->GetNextBox(&child);
}
// now add our border and padding and insets
AddBorderAndPadding(aBox, aSize);
AddInset(aBox,aSize);
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
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);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
aBox->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
// if completely redefined don't even ask our child for its size.
nsSize max(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
child->GetMaxSize(aBoxLayoutState, max);
AddMargin(child, max);
AddSmallestSize(aSize, max);
}
child->GetNextBox(&child);
}
// now add our border and padding and insets
AddBorderAndPadding(aBox, aSize);
AddInset(aBox, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::GetAscent(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
{
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(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
// if completely redefined don't even ask our child for its size.
nscoord ascent = 0;
child->GetAscent(aBoxLayoutState, ascent);
nsMargin margin;
child->GetMargin(margin);
ascent += margin.top + margin.bottom;
if (ascent > aAscent)
aAscent = ascent;
}
child->GetNextBox(&child);
}
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
{
nsRect clientRect;
aBox->GetClientRect(clientRect);
nsIBox* child = nsnull;
PRBool grow;
do {
aBox->GetChildBox(&child);
grow = PR_FALSE;
while (child)
{
nsMargin margin;
child->GetMargin(margin);
nsRect childRect(clientRect);
childRect.Deflate(margin);
child->SetBounds(aState, childRect);
child->Layout(aState);
child->GetBounds(childRect);
childRect.Inflate(margin);
// did the child push back on us and get bigger?
if (childRect.width > clientRect.width) {
clientRect.width = childRect.width;
grow = PR_TRUE;
}
if (childRect.height > clientRect.height) {
clientRect.height = childRect.height;
grow = PR_TRUE;
}
child->GetNextBox(&child);
}
} while(grow);
// if some HTML inside us got bigger we need to force ourselves to
// get bigger
nsRect bounds;
aBox->GetBounds(bounds);
nsMargin bp;
aBox->GetBorderAndPadding(bp);
clientRect.Inflate(bp);
aBox->GetInset(bp);
clientRect.Inflate(bp);
if (clientRect.width > bounds.width || clientRect.height > bounds.height)
{
if (clientRect.width > bounds.width)
bounds.width = clientRect.width;
if (clientRect.height > bounds.height)
bounds.height = clientRect.height;
aBox->SetBounds(aState, bounds);
}
return NS_OK;
}