1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 //
8 // Eric Vaughan
9 // Netscape Communications
10 //
11 // See documentation in associated header file
12 //
13
14 #include "nsGridLayout2.h"
15 #include "nsGridRowGroupLayout.h"
16 #include "nsGridRow.h"
17 #include "nsBox.h"
18 #include "nsIScrollableFrame.h"
19 #include "nsSprocketLayout.h"
20 #include "mozilla/ReflowInput.h"
21
NS_NewGridLayout2(nsIPresShell * aPresShell,nsBoxLayout ** aNewLayout)22 nsresult NS_NewGridLayout2(nsIPresShell* aPresShell, nsBoxLayout** aNewLayout) {
23 *aNewLayout = new nsGridLayout2(aPresShell);
24 NS_IF_ADDREF(*aNewLayout);
25
26 return NS_OK;
27 }
28
nsGridLayout2(nsIPresShell * aPresShell)29 nsGridLayout2::nsGridLayout2(nsIPresShell* aPresShell) : nsStackLayout() {}
30
~nsGridLayout2()31 nsGridLayout2::~nsGridLayout2() {}
32
33 // static
AddOffset(nsIFrame * aChild,nsSize & aSize)34 void nsGridLayout2::AddOffset(nsIFrame* aChild, nsSize& aSize) {
35 nsMargin offset;
36 GetOffset(aChild, offset);
37 aSize.width += offset.left;
38 aSize.height += offset.top;
39 }
40
41 NS_IMETHODIMP
XULLayout(nsIFrame * aBox,nsBoxLayoutState & aBoxLayoutState)42 nsGridLayout2::XULLayout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) {
43 // XXX This should be set a better way!
44 mGrid.SetBox(aBox);
45 NS_ASSERTION(aBox->GetXULLayoutManager() == this, "setting incorrect box");
46
47 nsresult rv = nsStackLayout::XULLayout(aBox, aBoxLayoutState);
48 #ifdef DEBUG_grid
49 mGrid.PrintCellMap();
50 #endif
51 return rv;
52 }
53
IntrinsicISizesDirty(nsIFrame * aBox,nsBoxLayoutState & aBoxLayoutState)54 void nsGridLayout2::IntrinsicISizesDirty(nsIFrame* aBox,
55 nsBoxLayoutState& aBoxLayoutState) {
56 nsStackLayout::IntrinsicISizesDirty(aBox, aBoxLayoutState);
57 // XXXldb We really don't need to do all the work that NeedsRebuild
58 // does; we just need to mark intrinsic widths dirty on the
59 // (row/column)(s/-groups).
60 mGrid.NeedsRebuild(aBoxLayoutState);
61 }
62
GetGrid(nsIFrame * aBox,int32_t * aIndex,nsGridRowLayout * aRequestor)63 nsGrid* nsGridLayout2::GetGrid(nsIFrame* aBox, int32_t* aIndex,
64 nsGridRowLayout* aRequestor) {
65 // XXX This should be set a better way!
66 mGrid.SetBox(aBox);
67 NS_ASSERTION(aBox->GetXULLayoutManager() == this, "setting incorrect box");
68 return &mGrid;
69 }
70
AddWidth(nsSize & aSize,nscoord aSize2,bool aIsHorizontal)71 void nsGridLayout2::AddWidth(nsSize& aSize, nscoord aSize2,
72 bool aIsHorizontal) {
73 nscoord& size = GET_WIDTH(aSize, aIsHorizontal);
74
75 if (size != NS_INTRINSICSIZE) {
76 if (aSize2 == NS_INTRINSICSIZE)
77 size = NS_INTRINSICSIZE;
78 else
79 size += aSize2;
80 }
81 }
82
GetXULMinSize(nsIFrame * aBox,nsBoxLayoutState & aState)83 nsSize nsGridLayout2::GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) {
84 nsSize minSize = nsStackLayout::GetXULMinSize(aBox, aState);
85
86 // if there are no <rows> tags that will sum up our columns,
87 // sum up our columns here.
88 nsSize total(0, 0);
89 nsIFrame* rowsBox = mGrid.GetRowsBox();
90 nsIFrame* columnsBox = mGrid.GetColumnsBox();
91 if (!rowsBox || !columnsBox) {
92 if (!rowsBox) {
93 // max height is the sum of our rows
94 int32_t rows = mGrid.GetRowCount();
95 for (int32_t i = 0; i < rows; i++) {
96 nscoord height = mGrid.GetMinRowHeight(aState, i, true);
97 AddWidth(total, height, false); // AddHeight
98 }
99 }
100
101 if (!columnsBox) {
102 // max height is the sum of our rows
103 int32_t columns = mGrid.GetColumnCount();
104 for (int32_t i = 0; i < columns; i++) {
105 nscoord width = mGrid.GetMinRowHeight(aState, i, false);
106 AddWidth(total, width, true); // AddWidth
107 }
108 }
109
110 AddMargin(aBox, total);
111 AddOffset(aBox, total);
112 AddLargestSize(minSize, total);
113 }
114
115 return minSize;
116 }
117
GetXULPrefSize(nsIFrame * aBox,nsBoxLayoutState & aState)118 nsSize nsGridLayout2::GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) {
119 nsSize pref = nsStackLayout::GetXULPrefSize(aBox, aState);
120
121 // if there are no <rows> tags that will sum up our columns,
122 // sum up our columns here.
123 nsSize total(0, 0);
124 nsIFrame* rowsBox = mGrid.GetRowsBox();
125 nsIFrame* columnsBox = mGrid.GetColumnsBox();
126 if (!rowsBox || !columnsBox) {
127 if (!rowsBox) {
128 // max height is the sum of our rows
129 int32_t rows = mGrid.GetRowCount();
130 for (int32_t i = 0; i < rows; i++) {
131 nscoord height = mGrid.GetPrefRowHeight(aState, i, true);
132 AddWidth(total, height, false); // AddHeight
133 }
134 }
135
136 if (!columnsBox) {
137 // max height is the sum of our rows
138 int32_t columns = mGrid.GetColumnCount();
139 for (int32_t i = 0; i < columns; i++) {
140 nscoord width = mGrid.GetPrefRowHeight(aState, i, false);
141 AddWidth(total, width, true); // AddWidth
142 }
143 }
144
145 AddMargin(aBox, total);
146 AddOffset(aBox, total);
147 AddLargestSize(pref, total);
148 }
149
150 return pref;
151 }
152
GetXULMaxSize(nsIFrame * aBox,nsBoxLayoutState & aState)153 nsSize nsGridLayout2::GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) {
154 nsSize maxSize = nsStackLayout::GetXULMaxSize(aBox, aState);
155
156 // if there are no <rows> tags that will sum up our columns,
157 // sum up our columns here.
158 nsSize total(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
159 nsIFrame* rowsBox = mGrid.GetRowsBox();
160 nsIFrame* columnsBox = mGrid.GetColumnsBox();
161 if (!rowsBox || !columnsBox) {
162 if (!rowsBox) {
163 total.height = 0;
164 // max height is the sum of our rows
165 int32_t rows = mGrid.GetRowCount();
166 for (int32_t i = 0; i < rows; i++) {
167 nscoord height = mGrid.GetMaxRowHeight(aState, i, true);
168 AddWidth(total, height, false); // AddHeight
169 }
170 }
171
172 if (!columnsBox) {
173 total.width = 0;
174 // max height is the sum of our rows
175 int32_t columns = mGrid.GetColumnCount();
176 for (int32_t i = 0; i < columns; i++) {
177 nscoord width = mGrid.GetMaxRowHeight(aState, i, false);
178 AddWidth(total, width, true); // AddWidth
179 }
180 }
181
182 AddMargin(aBox, total);
183 AddOffset(aBox, total);
184 AddSmallestSize(maxSize, total);
185 }
186
187 return maxSize;
188 }
189
BuildRows(nsIFrame * aBox,nsGridRow * aRows)190 int32_t nsGridLayout2::BuildRows(nsIFrame* aBox, nsGridRow* aRows) {
191 if (aBox) {
192 aRows[0].Init(aBox, true);
193 return 1;
194 }
195 return 0;
196 }
197
GetTotalMargin(nsIFrame * aBox,bool aIsHorizontal)198 nsMargin nsGridLayout2::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) {
199 nsMargin margin(0, 0, 0, 0);
200 return margin;
201 }
202
ChildrenInserted(nsIFrame * aBox,nsBoxLayoutState & aState,nsIFrame * aPrevBox,const nsFrameList::Slice & aNewChildren)203 void nsGridLayout2::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState,
204 nsIFrame* aPrevBox,
205 const nsFrameList::Slice& aNewChildren) {
206 mGrid.NeedsRebuild(aState);
207 }
208
ChildrenAppended(nsIFrame * aBox,nsBoxLayoutState & aState,const nsFrameList::Slice & aNewChildren)209 void nsGridLayout2::ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState,
210 const nsFrameList::Slice& aNewChildren) {
211 mGrid.NeedsRebuild(aState);
212 }
213
ChildrenRemoved(nsIFrame * aBox,nsBoxLayoutState & aState,nsIFrame * aChildList)214 void nsGridLayout2::ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState,
215 nsIFrame* aChildList) {
216 mGrid.NeedsRebuild(aState);
217 }
218
ChildrenSet(nsIFrame * aBox,nsBoxLayoutState & aState,nsIFrame * aChildList)219 void nsGridLayout2::ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState,
220 nsIFrame* aChildList) {
221 mGrid.NeedsRebuild(aState);
222 }
223
224 NS_IMPL_ADDREF_INHERITED(nsGridLayout2, nsStackLayout)
225 NS_IMPL_RELEASE_INHERITED(nsGridLayout2, nsStackLayout)
226
227 NS_INTERFACE_MAP_BEGIN(nsGridLayout2)
228 NS_INTERFACE_MAP_ENTRY(nsIGridPart)
229 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart)
230 NS_INTERFACE_MAP_END_INHERITING(nsStackLayout)
231