1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : //
39 : // Eric Vaughan
40 : // Netscape Communications
41 : //
42 : // See documentation in associated header file
43 : //
44 :
45 : #include "nsGridLayout2.h"
46 : #include "nsGridRowGroupLayout.h"
47 : #include "nsGridRow.h"
48 : #include "nsBox.h"
49 : #include "nsIScrollableFrame.h"
50 : #include "nsSprocketLayout.h"
51 :
52 : nsresult
53 0 : NS_NewGridLayout2( nsIPresShell* aPresShell, nsBoxLayout** aNewLayout)
54 : {
55 0 : *aNewLayout = new nsGridLayout2(aPresShell);
56 0 : NS_IF_ADDREF(*aNewLayout);
57 :
58 0 : return NS_OK;
59 :
60 : }
61 :
62 0 : nsGridLayout2::nsGridLayout2(nsIPresShell* aPresShell):nsStackLayout()
63 : {
64 0 : }
65 :
66 : // static
67 : void
68 0 : nsGridLayout2::AddOffset(nsBoxLayoutState& aState, nsIBox* aChild, nsSize& aSize)
69 : {
70 0 : nsMargin offset;
71 0 : GetOffset(aState, aChild, offset);
72 0 : aSize.width += offset.left;
73 0 : aSize.height += offset.top;
74 0 : }
75 :
76 : NS_IMETHODIMP
77 0 : nsGridLayout2::Layout(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState)
78 : {
79 : // XXX This should be set a better way!
80 0 : mGrid.SetBox(aBox);
81 0 : NS_ASSERTION(aBox->GetLayoutManager() == this, "setting incorrect box");
82 :
83 0 : nsresult rv = nsStackLayout::Layout(aBox, aBoxLayoutState);
84 : #ifdef DEBUG_grid
85 : mGrid.PrintCellMap();
86 : #endif
87 0 : return rv;
88 : }
89 :
90 : void
91 0 : nsGridLayout2::IntrinsicWidthsDirty(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState)
92 : {
93 0 : nsStackLayout::IntrinsicWidthsDirty(aBox, aBoxLayoutState);
94 : // XXXldb We really don't need to do all the work that NeedsRebuild
95 : // does; we just need to mark intrinsic widths dirty on the
96 : // (row/column)(s/-groups).
97 0 : mGrid.NeedsRebuild(aBoxLayoutState);
98 0 : }
99 :
100 : nsGrid*
101 0 : nsGridLayout2::GetGrid(nsIBox* aBox, PRInt32* aIndex, nsGridRowLayout* aRequestor)
102 : {
103 : // XXX This should be set a better way!
104 0 : mGrid.SetBox(aBox);
105 0 : NS_ASSERTION(aBox->GetLayoutManager() == this, "setting incorrect box");
106 0 : return &mGrid;
107 : }
108 :
109 : void
110 0 : nsGridLayout2::AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal)
111 : {
112 0 : nscoord& size = GET_WIDTH(aSize, aIsHorizontal);
113 :
114 0 : if (size != NS_INTRINSICSIZE) {
115 0 : if (aSize2 == NS_INTRINSICSIZE)
116 0 : size = NS_INTRINSICSIZE;
117 : else
118 0 : size += aSize2;
119 : }
120 0 : }
121 :
122 : nsSize
123 0 : nsGridLayout2::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState)
124 : {
125 0 : nsSize minSize = nsStackLayout::GetMinSize(aBox, aState);
126 :
127 : // if there are no <rows> tags that will sum up our columns,
128 : // sum up our columns here.
129 0 : nsSize total(0,0);
130 0 : nsIBox* rowsBox = mGrid.GetRowsBox();
131 0 : nsIBox* columnsBox = mGrid.GetColumnsBox();
132 0 : if (!rowsBox || !columnsBox) {
133 0 : if (!rowsBox) {
134 : // max height is the sum of our rows
135 0 : PRInt32 rows = mGrid.GetRowCount();
136 0 : for (PRInt32 i=0; i < rows; i++)
137 : {
138 0 : nscoord height = mGrid.GetMinRowHeight(aState, i, true);
139 0 : AddWidth(total, height, false); // AddHeight
140 : }
141 : }
142 :
143 0 : if (!columnsBox) {
144 : // max height is the sum of our rows
145 0 : PRInt32 columns = mGrid.GetColumnCount();
146 0 : for (PRInt32 i=0; i < columns; i++)
147 : {
148 0 : nscoord width = mGrid.GetMinRowHeight(aState, i, false);
149 0 : AddWidth(total, width, true); // AddWidth
150 : }
151 : }
152 :
153 0 : AddMargin(aBox, total);
154 0 : AddOffset(aState, aBox, total);
155 0 : AddLargestSize(minSize, total);
156 : }
157 :
158 : return minSize;
159 : }
160 :
161 : nsSize
162 0 : nsGridLayout2::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aState)
163 : {
164 0 : nsSize pref = nsStackLayout::GetPrefSize(aBox, aState);
165 :
166 : // if there are no <rows> tags that will sum up our columns,
167 : // sum up our columns here.
168 0 : nsSize total(0,0);
169 0 : nsIBox* rowsBox = mGrid.GetRowsBox();
170 0 : nsIBox* columnsBox = mGrid.GetColumnsBox();
171 0 : if (!rowsBox || !columnsBox) {
172 0 : if (!rowsBox) {
173 : // max height is the sum of our rows
174 0 : PRInt32 rows = mGrid.GetRowCount();
175 0 : for (PRInt32 i=0; i < rows; i++)
176 : {
177 0 : nscoord height = mGrid.GetPrefRowHeight(aState, i, true);
178 0 : AddWidth(total, height, false); // AddHeight
179 : }
180 : }
181 :
182 0 : if (!columnsBox) {
183 : // max height is the sum of our rows
184 0 : PRInt32 columns = mGrid.GetColumnCount();
185 0 : for (PRInt32 i=0; i < columns; i++)
186 : {
187 0 : nscoord width = mGrid.GetPrefRowHeight(aState, i, false);
188 0 : AddWidth(total, width, true); // AddWidth
189 : }
190 : }
191 :
192 0 : AddMargin(aBox, total);
193 0 : AddOffset(aState, aBox, total);
194 0 : AddLargestSize(pref, total);
195 : }
196 :
197 : return pref;
198 : }
199 :
200 : nsSize
201 0 : nsGridLayout2::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aState)
202 : {
203 0 : nsSize maxSize = nsStackLayout::GetMaxSize(aBox, aState);
204 :
205 : // if there are no <rows> tags that will sum up our columns,
206 : // sum up our columns here.
207 0 : nsSize total(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
208 0 : nsIBox* rowsBox = mGrid.GetRowsBox();
209 0 : nsIBox* columnsBox = mGrid.GetColumnsBox();
210 0 : if (!rowsBox || !columnsBox) {
211 0 : if (!rowsBox) {
212 0 : total.height = 0;
213 : // max height is the sum of our rows
214 0 : PRInt32 rows = mGrid.GetRowCount();
215 0 : for (PRInt32 i=0; i < rows; i++)
216 : {
217 0 : nscoord height = mGrid.GetMaxRowHeight(aState, i, true);
218 0 : AddWidth(total, height, false); // AddHeight
219 : }
220 : }
221 :
222 0 : if (!columnsBox) {
223 0 : total.width = 0;
224 : // max height is the sum of our rows
225 0 : PRInt32 columns = mGrid.GetColumnCount();
226 0 : for (PRInt32 i=0; i < columns; i++)
227 : {
228 0 : nscoord width = mGrid.GetMaxRowHeight(aState, i, false);
229 0 : AddWidth(total, width, true); // AddWidth
230 : }
231 : }
232 :
233 0 : AddMargin(aBox, total);
234 0 : AddOffset(aState, aBox, total);
235 0 : AddSmallestSize(maxSize, total);
236 : }
237 :
238 : return maxSize;
239 : }
240 :
241 : PRInt32
242 0 : nsGridLayout2::BuildRows(nsIBox* aBox, nsGridRow* aRows)
243 : {
244 0 : if (aBox) {
245 0 : aRows[0].Init(aBox, true);
246 0 : return 1;
247 : }
248 0 : return 0;
249 : }
250 :
251 : nsMargin
252 0 : nsGridLayout2::GetTotalMargin(nsIBox* aBox, bool aIsHorizontal)
253 : {
254 0 : nsMargin margin(0,0,0,0);
255 : return margin;
256 : }
257 :
258 : void
259 0 : nsGridLayout2::ChildrenInserted(nsIBox* aBox, nsBoxLayoutState& aState,
260 : nsIBox* aPrevBox,
261 : const nsFrameList::Slice& aNewChildren)
262 : {
263 0 : mGrid.NeedsRebuild(aState);
264 0 : }
265 :
266 : void
267 0 : nsGridLayout2::ChildrenAppended(nsIBox* aBox, nsBoxLayoutState& aState,
268 : const nsFrameList::Slice& aNewChildren)
269 : {
270 0 : mGrid.NeedsRebuild(aState);
271 0 : }
272 :
273 : void
274 0 : nsGridLayout2::ChildrenRemoved(nsIBox* aBox, nsBoxLayoutState& aState,
275 : nsIBox* aChildList)
276 : {
277 0 : mGrid.NeedsRebuild(aState);
278 0 : }
279 :
280 : void
281 0 : nsGridLayout2::ChildrenSet(nsIBox* aBox, nsBoxLayoutState& aState,
282 : nsIBox* aChildList)
283 : {
284 0 : mGrid.NeedsRebuild(aState);
285 0 : }
286 :
287 0 : NS_IMPL_ADDREF_INHERITED(nsGridLayout2, nsStackLayout)
288 0 : NS_IMPL_RELEASE_INHERITED(nsGridLayout2, nsStackLayout)
289 :
290 0 : NS_INTERFACE_MAP_BEGIN(nsGridLayout2)
291 0 : NS_INTERFACE_MAP_ENTRY(nsIGridPart)
292 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart)
293 0 : NS_INTERFACE_MAP_END_INHERITING(nsStackLayout)
|