243 lines
6.6 KiB
C++
243 lines
6.6 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 "nsTempleLayout.h"
|
|
#include "nsIBox.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIScrollableFrame.h"
|
|
|
|
nsresult
|
|
NS_NewTempleLayout( nsIPresShell* aPresShell, nsCOMPtr<nsIBoxLayout>& aNewLayout)
|
|
{
|
|
aNewLayout = new nsTempleLayout(aPresShell);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsTempleLayout::nsTempleLayout(nsIPresShell* aPresShell):nsMonumentLayout(aPresShell), mMonuments(nsnull)
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::CastToTemple(nsTempleLayout** aTemple)
|
|
{
|
|
*aTemple = this;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::EnscriptionChanged(nsBoxLayoutState& aState, PRInt32 aIndex)
|
|
{
|
|
// if a cell changes size.
|
|
if (mMonuments) {
|
|
nsBoxSizeList* size = mMonuments->GetAt(aIndex);
|
|
if (size)
|
|
size->Desecrate(aState);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::GetMonumentList(nsIBox* aBox, nsBoxLayoutState& aState, nsBoxSizeList** aList)
|
|
{
|
|
if (mMonuments) {
|
|
*aList = mMonuments;
|
|
return NS_OK;
|
|
}
|
|
|
|
// run through our children.
|
|
// ask each child for its monument list
|
|
// append the list to our list
|
|
nsIBox* firstChild = nsnull;
|
|
aBox->GetChildBox(&firstChild);
|
|
|
|
nsBoxSizeList* current = nsnull;
|
|
nsCOMPtr<nsIMonument> monument;
|
|
nsMonumentIterator it(firstChild);
|
|
|
|
nsIBox* box = nsnull;
|
|
while(it.GetNextMonument(getter_AddRefs(monument))) {
|
|
|
|
it.GetBox(&box);
|
|
|
|
current = mMonuments;
|
|
nsBoxSizeList* node = nsnull;
|
|
monument->GetMonumentList(box, aState, &node);
|
|
|
|
while(node)
|
|
{
|
|
if (!mMonuments) {
|
|
mMonuments = new nsBoxSizeListImpl(firstChild);
|
|
current = mMonuments;
|
|
}
|
|
|
|
current->Append(aState, node);
|
|
|
|
node = node->GetAdjacent();
|
|
|
|
if (node && !current->GetAdjacent()) {
|
|
nsBoxSizeList* newOne = new nsBoxSizeListImpl(box);
|
|
current->SetAdjacent(aState, newOne);
|
|
current = newOne;
|
|
} else {
|
|
current = current->GetAdjacent();
|
|
}
|
|
}
|
|
}
|
|
|
|
*aList = mMonuments;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::BuildBoxSizeList(nsIBox* aBox, nsBoxLayoutState& aState, nsBoxSize*& aFirst, nsBoxSize*& aLast, PRBool aIsHorizontal)
|
|
{
|
|
// ok we need to build a nsBoxSize for each obelisk in this temple. We will then return the list of them.
|
|
// We are just returning a flattened list that we will use to layout our each cell.
|
|
nsIBox* box = nsnull;
|
|
aBox->GetChildBox(&box);
|
|
|
|
aFirst = nsnull;
|
|
aLast = nsnull;
|
|
|
|
nsBoxSize* first;
|
|
nsBoxSize* last;
|
|
PRInt32 count = 0;
|
|
|
|
nsCOMPtr<nsIBoxLayout> layout;
|
|
|
|
nsLayoutIterator it(box);
|
|
|
|
while(it.GetNextLayout(getter_AddRefs(layout))) {
|
|
|
|
it.GetBox(&box);
|
|
|
|
if (layout) {
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsIMonument> monument = do_QueryInterface(layout, &rv);
|
|
|
|
if (monument)
|
|
monument->BuildBoxSizeList(box, aState, first, last, aIsHorizontal);
|
|
else {
|
|
nsMonumentLayout::BuildBoxSizeList(box, aState, first, last, aIsHorizontal);
|
|
first->bogus = PR_TRUE;
|
|
}
|
|
|
|
if (count == 0)
|
|
aFirst = first;
|
|
else if (aLast)
|
|
(aLast)->next = first;
|
|
aLast = last;
|
|
}
|
|
|
|
count++;
|
|
}
|
|
|
|
// ok now we might have a margin or border. If we do then we need to take that into account. One example
|
|
// might be if we are oriented vertically making us a "columns" and we contain a horizontal obelisk "row".
|
|
// Now say we have a left border of 10px. Well if we just layed things out then the whole row would be pushed over and
|
|
// the columns would not not line up. So we must take the space from somewhere. So if its on the left we take from the first
|
|
// child (which is leftmost) and if its on the right we take from the last child (which is rightmost). So for our example we
|
|
// need to subtract 10px from the first child.
|
|
|
|
// so get the border and padding and add them up.
|
|
nsMargin borderPadding(0,0,0,0);
|
|
aBox->GetBorderAndPadding(borderPadding);
|
|
nsMargin margin(0,0,0,0);
|
|
aBox->GetMargin(margin);
|
|
|
|
// add the margins up
|
|
nsMargin leftMargin(borderPadding.left + margin.left, borderPadding.top + margin.top, 0, 0);
|
|
nsMargin rightMargin(0,0, borderPadding.right + margin.right, borderPadding.bottom + margin.bottom);
|
|
|
|
// Subtract them out.
|
|
PRBool isHorizontal = PR_FALSE;
|
|
aBox->GetOrientation(isHorizontal);
|
|
|
|
if (aFirst)
|
|
aFirst->Add(leftMargin,isHorizontal);
|
|
|
|
if (aLast)
|
|
aLast->Add(rightMargin,isHorizontal);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::ChildrenInserted(nsIBox* aBox, nsBoxLayoutState& aState, nsIBox* aPrevBox, nsIBox* aChildList)
|
|
{
|
|
DesecrateMonuments(aBox, aState);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::ChildrenAppended(nsIBox* aBox, nsBoxLayoutState& aState, nsIBox* aChildList)
|
|
{
|
|
DesecrateMonuments(aBox, aState);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::ChildrenRemoved(nsIBox* aBox, nsBoxLayoutState& aState, nsIBox* aChildList)
|
|
{
|
|
DesecrateMonuments(aBox, aState);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::DesecrateMonuments(nsIBox* aBox, nsBoxLayoutState& aState)
|
|
{
|
|
nsCOMPtr<nsIMonument> parent;
|
|
nsCOMPtr<nsIBox> parentBox;
|
|
GetParentMonument(aBox, parentBox, getter_AddRefs(parent));
|
|
if (parent)
|
|
parent->DesecrateMonuments(parentBox, aState);
|
|
|
|
if (mMonuments) {
|
|
nsBoxSizeList* tmp = mMonuments;
|
|
mMonuments->Release(aState);
|
|
mMonuments = nsnull;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// redefined because the normal GetMinSize in sprocket looks at flex
|
|
// if the child is not flexible then its min size is its pref size.
|
|
// but in this case its up to the column. The column's flex is the
|
|
// flex thats used.
|
|
NS_IMETHODIMP
|
|
nsTempleLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSize)
|
|
{
|
|
return nsSprocketLayout::GetMinSize(aBox, aState, aSize);
|
|
}
|
|
|