Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 //
7 // Eric Vaughan
8 // Netscape Communications
9 //
10 // See documentation in associated header file
11 //
14 /*
15 * The nsGridRowGroupLayout implements the <rows> or <columns> tag in a grid.
16 */
18 #include "nsGridRowGroupLayout.h"
19 #include "nsCOMPtr.h"
20 #include "nsIScrollableFrame.h"
21 #include "nsBoxLayoutState.h"
22 #include "nsGridLayout2.h"
23 #include "nsGridRow.h"
24 #include "nsHTMLReflowState.h"
26 already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout()
27 {
28 nsRefPtr<nsBoxLayout> layout = new nsGridRowGroupLayout();
29 return layout.forget();
30 }
32 nsGridRowGroupLayout::nsGridRowGroupLayout():nsGridRowLayout(), mRowCount(0)
33 {
34 }
36 nsGridRowGroupLayout::~nsGridRowGroupLayout()
37 {
38 }
40 void
41 nsGridRowGroupLayout::ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState)
42 {
43 int32_t index = 0;
44 nsGrid* grid = GetGrid(aBox, &index);
45 bool isHorizontal = IsHorizontal(aBox);
47 if (grid)
48 grid->RowAddedOrRemoved(aState, index, isHorizontal);
49 }
51 void
52 nsGridRowGroupLayout::AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal)
53 {
54 nscoord& size = GET_WIDTH(aSize, aIsHorizontal);
56 if (size == NS_INTRINSICSIZE || aSize2 == NS_INTRINSICSIZE)
57 size = NS_INTRINSICSIZE;
58 else
59 size += aSize2;
60 }
62 nsSize
63 nsGridRowGroupLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState)
64 {
65 nsSize vpref = nsGridRowLayout::GetPrefSize(aBox, aState);
68 /* It is possible that we could have some extra columns. This is when less columns in XUL were
69 * defined that needed. And example might be a grid with 3 defined columns but a row with 4 cells in
70 * it. We would need an extra column to make the grid work. But because that extra column does not
71 * have a box associated with it we must add its size in manually. Remember we could have extra rows
72 * as well.
73 */
75 int32_t index = 0;
76 nsGrid* grid = GetGrid(aBox, &index);
78 if (grid)
79 {
80 // make sure we add in extra columns sizes as well
81 bool isHorizontal = IsHorizontal(aBox);
82 int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal);
83 int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal);
84 for (int32_t i=0; i < extraColumns; i++)
85 {
86 nscoord pref =
87 grid->GetPrefRowHeight(aState, i+start, !isHorizontal); // GetPrefColumnWidth
89 AddWidth(vpref, pref, isHorizontal);
90 }
91 }
93 return vpref;
94 }
96 nsSize
97 nsGridRowGroupLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState)
98 {
99 nsSize maxSize = nsGridRowLayout::GetMaxSize(aBox, aState);
101 int32_t index = 0;
102 nsGrid* grid = GetGrid(aBox, &index);
104 if (grid)
105 {
106 // make sure we add in extra columns sizes as well
107 bool isHorizontal = IsHorizontal(aBox);
108 int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal);
109 int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal);
110 for (int32_t i=0; i < extraColumns; i++)
111 {
112 nscoord max =
113 grid->GetMaxRowHeight(aState, i+start, !isHorizontal); // GetMaxColumnWidth
115 AddWidth(maxSize, max, isHorizontal);
116 }
117 }
119 return maxSize;
120 }
122 nsSize
123 nsGridRowGroupLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState)
124 {
125 nsSize minSize = nsGridRowLayout::GetMinSize(aBox, aState);
127 int32_t index = 0;
128 nsGrid* grid = GetGrid(aBox, &index);
130 if (grid)
131 {
132 // make sure we add in extra columns sizes as well
133 bool isHorizontal = IsHorizontal(aBox);
134 int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal);
135 int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal);
136 for (int32_t i=0; i < extraColumns; i++)
137 {
138 nscoord min =
139 grid->GetMinRowHeight(aState, i+start, !isHorizontal); // GetMinColumnWidth
140 AddWidth(minSize, min, isHorizontal);
141 }
142 }
144 return minSize;
145 }
147 /*
148 * Run down through our children dirtying them recursively.
149 */
150 void
151 nsGridRowGroupLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState)
152 {
153 if (aBox) {
154 // mark us dirty
155 // XXXldb We probably don't want to walk up the ancestor chain
156 // calling MarkIntrinsicWidthsDirty for every row group.
157 aState.PresShell()->FrameNeedsReflow(aBox, nsIPresShell::eTreeChange,
158 NS_FRAME_IS_DIRTY);
159 nsIFrame* child = aBox->GetChildBox();
161 while(child) {
163 // walk into scrollframes
164 nsIFrame* deepChild = nsGrid::GetScrolledBox(child);
166 // walk into other monuments
167 nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild);
168 if (monument)
169 monument->DirtyRows(deepChild, aState);
171 child = child->GetNextBox();
172 }
173 }
174 }
177 void
178 nsGridRowGroupLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount)
179 {
180 if (aBox) {
181 int32_t startCount = aRowCount;
183 nsIFrame* child = aBox->GetChildBox();
185 while(child) {
187 // first see if it is a scrollframe. If so walk down into it and get the scrolled child
188 nsIFrame* deepChild = nsGrid::GetScrolledBox(child);
190 nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild);
191 if (monument) {
192 monument->CountRowsColumns(deepChild, aRowCount, aComputedColumnCount);
193 child = child->GetNextBox();
194 deepChild = child;
195 continue;
196 }
198 child = child->GetNextBox();
200 // if not a monument. Then count it. It will be a bogus row
201 aRowCount++;
202 }
204 mRowCount = aRowCount - startCount;
205 }
206 }
209 /**
210 * Fill out the given row structure recursively
211 */
212 int32_t
213 nsGridRowGroupLayout::BuildRows(nsIFrame* aBox, nsGridRow* aRows)
214 {
215 int32_t rowCount = 0;
217 if (aBox) {
218 nsIFrame* child = aBox->GetChildBox();
220 while(child) {
222 // first see if it is a scrollframe. If so walk down into it and get the scrolled child
223 nsIFrame* deepChild = nsGrid::GetScrolledBox(child);
225 nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild);
226 if (monument) {
227 rowCount += monument->BuildRows(deepChild, &aRows[rowCount]);
228 child = child->GetNextBox();
229 deepChild = child;
230 continue;
231 }
233 aRows[rowCount].Init(child, true);
235 child = child->GetNextBox();
237 // if not a monument. Then count it. It will be a bogus row
238 rowCount++;
239 }
240 }
242 return rowCount;
243 }
245 nsMargin
246 nsGridRowGroupLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal)
247 {
248 // group have border and padding added to the total margin
250 nsMargin margin = nsGridRowLayout::GetTotalMargin(aBox, aIsHorizontal);
252 // make sure we have the scrollframe on the outside if it has one.
253 // that's where the border is.
254 aBox = nsGrid::GetScrollBox(aBox);
256 // add our border/padding to it
257 nsMargin borderPadding(0,0,0,0);
258 aBox->GetBorderAndPadding(borderPadding);
259 margin += borderPadding;
261 return margin;
262 }