michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // michael@0: // Eric Vaughan michael@0: // Netscape Communications michael@0: // michael@0: // See documentation in associated header file michael@0: // michael@0: michael@0: #include "nsGridLayout2.h" michael@0: #include "nsGridRowGroupLayout.h" michael@0: #include "nsGridRow.h" michael@0: #include "nsBox.h" michael@0: #include "nsIScrollableFrame.h" michael@0: #include "nsSprocketLayout.h" michael@0: #include "nsHTMLReflowState.h" michael@0: michael@0: nsresult michael@0: NS_NewGridLayout2( nsIPresShell* aPresShell, nsBoxLayout** aNewLayout) michael@0: { michael@0: *aNewLayout = new nsGridLayout2(aPresShell); michael@0: NS_IF_ADDREF(*aNewLayout); michael@0: michael@0: return NS_OK; michael@0: michael@0: } michael@0: michael@0: nsGridLayout2::nsGridLayout2(nsIPresShell* aPresShell):nsStackLayout() michael@0: { michael@0: } michael@0: michael@0: // static michael@0: void michael@0: nsGridLayout2::AddOffset(nsBoxLayoutState& aState, nsIFrame* aChild, nsSize& aSize) michael@0: { michael@0: nsMargin offset; michael@0: GetOffset(aState, aChild, offset); michael@0: aSize.width += offset.left; michael@0: aSize.height += offset.top; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsGridLayout2::Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) michael@0: { michael@0: // XXX This should be set a better way! michael@0: mGrid.SetBox(aBox); michael@0: NS_ASSERTION(aBox->GetLayoutManager() == this, "setting incorrect box"); michael@0: michael@0: nsresult rv = nsStackLayout::Layout(aBox, aBoxLayoutState); michael@0: #ifdef DEBUG_grid michael@0: mGrid.PrintCellMap(); michael@0: #endif michael@0: return rv; michael@0: } michael@0: michael@0: void michael@0: nsGridLayout2::IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) michael@0: { michael@0: nsStackLayout::IntrinsicWidthsDirty(aBox, aBoxLayoutState); michael@0: // XXXldb We really don't need to do all the work that NeedsRebuild michael@0: // does; we just need to mark intrinsic widths dirty on the michael@0: // (row/column)(s/-groups). michael@0: mGrid.NeedsRebuild(aBoxLayoutState); michael@0: } michael@0: michael@0: nsGrid* michael@0: nsGridLayout2::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor) michael@0: { michael@0: // XXX This should be set a better way! michael@0: mGrid.SetBox(aBox); michael@0: NS_ASSERTION(aBox->GetLayoutManager() == this, "setting incorrect box"); michael@0: return &mGrid; michael@0: } michael@0: michael@0: void michael@0: nsGridLayout2::AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal) michael@0: { michael@0: nscoord& size = GET_WIDTH(aSize, aIsHorizontal); michael@0: michael@0: if (size != NS_INTRINSICSIZE) { michael@0: if (aSize2 == NS_INTRINSICSIZE) michael@0: size = NS_INTRINSICSIZE; michael@0: else michael@0: size += aSize2; michael@0: } michael@0: } michael@0: michael@0: nsSize michael@0: nsGridLayout2::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) michael@0: { michael@0: nsSize minSize = nsStackLayout::GetMinSize(aBox, aState); michael@0: michael@0: // if there are no tags that will sum up our columns, michael@0: // sum up our columns here. michael@0: nsSize total(0,0); michael@0: nsIFrame* rowsBox = mGrid.GetRowsBox(); michael@0: nsIFrame* columnsBox = mGrid.GetColumnsBox(); michael@0: if (!rowsBox || !columnsBox) { michael@0: if (!rowsBox) { michael@0: // max height is the sum of our rows michael@0: int32_t rows = mGrid.GetRowCount(); michael@0: for (int32_t i=0; i < rows; i++) michael@0: { michael@0: nscoord height = mGrid.GetMinRowHeight(aState, i, true); michael@0: AddWidth(total, height, false); // AddHeight michael@0: } michael@0: } michael@0: michael@0: if (!columnsBox) { michael@0: // max height is the sum of our rows michael@0: int32_t columns = mGrid.GetColumnCount(); michael@0: for (int32_t i=0; i < columns; i++) michael@0: { michael@0: nscoord width = mGrid.GetMinRowHeight(aState, i, false); michael@0: AddWidth(total, width, true); // AddWidth michael@0: } michael@0: } michael@0: michael@0: AddMargin(aBox, total); michael@0: AddOffset(aState, aBox, total); michael@0: AddLargestSize(minSize, total); michael@0: } michael@0: michael@0: return minSize; michael@0: } michael@0: michael@0: nsSize michael@0: nsGridLayout2::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) michael@0: { michael@0: nsSize pref = nsStackLayout::GetPrefSize(aBox, aState); michael@0: michael@0: // if there are no tags that will sum up our columns, michael@0: // sum up our columns here. michael@0: nsSize total(0,0); michael@0: nsIFrame* rowsBox = mGrid.GetRowsBox(); michael@0: nsIFrame* columnsBox = mGrid.GetColumnsBox(); michael@0: if (!rowsBox || !columnsBox) { michael@0: if (!rowsBox) { michael@0: // max height is the sum of our rows michael@0: int32_t rows = mGrid.GetRowCount(); michael@0: for (int32_t i=0; i < rows; i++) michael@0: { michael@0: nscoord height = mGrid.GetPrefRowHeight(aState, i, true); michael@0: AddWidth(total, height, false); // AddHeight michael@0: } michael@0: } michael@0: michael@0: if (!columnsBox) { michael@0: // max height is the sum of our rows michael@0: int32_t columns = mGrid.GetColumnCount(); michael@0: for (int32_t i=0; i < columns; i++) michael@0: { michael@0: nscoord width = mGrid.GetPrefRowHeight(aState, i, false); michael@0: AddWidth(total, width, true); // AddWidth michael@0: } michael@0: } michael@0: michael@0: AddMargin(aBox, total); michael@0: AddOffset(aState, aBox, total); michael@0: AddLargestSize(pref, total); michael@0: } michael@0: michael@0: return pref; michael@0: } michael@0: michael@0: nsSize michael@0: nsGridLayout2::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) michael@0: { michael@0: nsSize maxSize = nsStackLayout::GetMaxSize(aBox, aState); michael@0: michael@0: // if there are no tags that will sum up our columns, michael@0: // sum up our columns here. michael@0: nsSize total(NS_INTRINSICSIZE, NS_INTRINSICSIZE); michael@0: nsIFrame* rowsBox = mGrid.GetRowsBox(); michael@0: nsIFrame* columnsBox = mGrid.GetColumnsBox(); michael@0: if (!rowsBox || !columnsBox) { michael@0: if (!rowsBox) { michael@0: total.height = 0; michael@0: // max height is the sum of our rows michael@0: int32_t rows = mGrid.GetRowCount(); michael@0: for (int32_t i=0; i < rows; i++) michael@0: { michael@0: nscoord height = mGrid.GetMaxRowHeight(aState, i, true); michael@0: AddWidth(total, height, false); // AddHeight michael@0: } michael@0: } michael@0: michael@0: if (!columnsBox) { michael@0: total.width = 0; michael@0: // max height is the sum of our rows michael@0: int32_t columns = mGrid.GetColumnCount(); michael@0: for (int32_t i=0; i < columns; i++) michael@0: { michael@0: nscoord width = mGrid.GetMaxRowHeight(aState, i, false); michael@0: AddWidth(total, width, true); // AddWidth michael@0: } michael@0: } michael@0: michael@0: AddMargin(aBox, total); michael@0: AddOffset(aState, aBox, total); michael@0: AddSmallestSize(maxSize, total); michael@0: } michael@0: michael@0: return maxSize; michael@0: } michael@0: michael@0: int32_t michael@0: nsGridLayout2::BuildRows(nsIFrame* aBox, nsGridRow* aRows) michael@0: { michael@0: if (aBox) { michael@0: aRows[0].Init(aBox, true); michael@0: return 1; michael@0: } michael@0: return 0; michael@0: } michael@0: michael@0: nsMargin michael@0: nsGridLayout2::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) michael@0: { michael@0: nsMargin margin(0,0,0,0); michael@0: return margin; michael@0: } michael@0: michael@0: void michael@0: nsGridLayout2::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, michael@0: nsIFrame* aPrevBox, michael@0: const nsFrameList::Slice& aNewChildren) michael@0: { michael@0: mGrid.NeedsRebuild(aState); michael@0: } michael@0: michael@0: void michael@0: nsGridLayout2::ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, michael@0: const nsFrameList::Slice& aNewChildren) michael@0: { michael@0: mGrid.NeedsRebuild(aState); michael@0: } michael@0: michael@0: void michael@0: nsGridLayout2::ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, michael@0: nsIFrame* aChildList) michael@0: { michael@0: mGrid.NeedsRebuild(aState); michael@0: } michael@0: michael@0: void michael@0: nsGridLayout2::ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, michael@0: nsIFrame* aChildList) michael@0: { michael@0: mGrid.NeedsRebuild(aState); michael@0: } michael@0: michael@0: NS_IMPL_ADDREF_INHERITED(nsGridLayout2, nsStackLayout) michael@0: NS_IMPL_RELEASE_INHERITED(nsGridLayout2, nsStackLayout) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(nsGridLayout2) michael@0: NS_INTERFACE_MAP_ENTRY(nsIGridPart) michael@0: NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart) michael@0: NS_INTERFACE_MAP_END_INHERITING(nsStackLayout)