Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/xul/grid/nsGridRowGroupLayout.cpp
Line
Count
Source (jump to first uncovered line)
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
15
/*
16
 * The nsGridRowGroupLayout implements the <rows> or <columns> tag in a grid.
17
 */
18
19
#include "nsGridRowGroupLayout.h"
20
#include "nsCOMPtr.h"
21
#include "nsIScrollableFrame.h"
22
#include "nsBox.h"
23
#include "nsBoxLayoutState.h"
24
#include "nsGridLayout2.h"
25
#include "nsGridRow.h"
26
#include "mozilla/ReflowInput.h"
27
28
already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout()
29
0
{
30
0
  RefPtr<nsBoxLayout> layout = new nsGridRowGroupLayout();
31
0
  return layout.forget();
32
0
}
33
34
nsGridRowGroupLayout::nsGridRowGroupLayout():nsGridRowLayout(), mRowCount(0)
35
0
{
36
0
}
37
38
nsGridRowGroupLayout::~nsGridRowGroupLayout()
39
0
{
40
0
}
41
42
void
43
nsGridRowGroupLayout::ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState)
44
0
{
45
0
  int32_t index = 0;
46
0
  nsGrid* grid = GetGrid(aBox, &index);
47
0
  bool isHorizontal = IsXULHorizontal(aBox);
48
0
49
0
  if (grid)
50
0
    grid->RowAddedOrRemoved(aState, index, isHorizontal);
51
0
}
52
53
void
54
nsGridRowGroupLayout::AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal)
55
0
{
56
0
  nscoord& size = GET_WIDTH(aSize, aIsHorizontal);
57
0
58
0
  if (size == NS_INTRINSICSIZE || aSize2 == NS_INTRINSICSIZE)
59
0
    size = NS_INTRINSICSIZE;
60
0
  else
61
0
    size += aSize2;
62
0
}
63
64
nsSize
65
nsGridRowGroupLayout::GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState)
66
0
{
67
0
  nsSize vpref = nsGridRowLayout::GetXULPrefSize(aBox, aState);
68
0
69
0
70
0
 /* It is possible that we could have some extra columns. This is when less columns in XUL were
71
0
  * defined that needed. And example might be a grid with 3 defined columns but a row with 4 cells in
72
0
  * it. We would need an extra column to make the grid work. But because that extra column does not
73
0
  * have a box associated with it we must add its size in manually. Remember we could have extra rows
74
0
  * as well.
75
0
  */
76
0
77
0
  int32_t index = 0;
78
0
  nsGrid* grid = GetGrid(aBox, &index);
79
0
80
0
  if (grid)
81
0
  {
82
0
    // make sure we add in extra columns sizes as well
83
0
    bool isHorizontal = IsXULHorizontal(aBox);
84
0
    int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal);
85
0
    int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal);
86
0
    for (int32_t i=0; i < extraColumns; i++)
87
0
    {
88
0
      nscoord pref =
89
0
        grid->GetPrefRowHeight(aState, i+start, !isHorizontal); // GetPrefColumnWidth
90
0
91
0
      AddWidth(vpref, pref, isHorizontal);
92
0
    }
93
0
  }
94
0
95
0
  return vpref;
96
0
}
97
98
nsSize
99
nsGridRowGroupLayout::GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState)
100
0
{
101
0
 nsSize maxSize = nsGridRowLayout::GetXULMaxSize(aBox, aState);
102
0
103
0
  int32_t index = 0;
104
0
  nsGrid* grid = GetGrid(aBox, &index);
105
0
106
0
  if (grid)
107
0
  {
108
0
    // make sure we add in extra columns sizes as well
109
0
    bool isHorizontal = IsXULHorizontal(aBox);
110
0
    int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal);
111
0
    int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal);
112
0
    for (int32_t i=0; i < extraColumns; i++)
113
0
    {
114
0
      nscoord max =
115
0
        grid->GetMaxRowHeight(aState, i+start, !isHorizontal); // GetMaxColumnWidth
116
0
117
0
      AddWidth(maxSize, max, isHorizontal);
118
0
    }
119
0
  }
120
0
121
0
  return maxSize;
122
0
}
123
124
nsSize
125
nsGridRowGroupLayout::GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aState)
126
0
{
127
0
  nsSize minSize = nsGridRowLayout::GetXULMinSize(aBox, aState);
128
0
129
0
  int32_t index = 0;
130
0
  nsGrid* grid = GetGrid(aBox, &index);
131
0
132
0
  if (grid)
133
0
  {
134
0
    // make sure we add in extra columns sizes as well
135
0
    bool isHorizontal = IsXULHorizontal(aBox);
136
0
    int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal);
137
0
    int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal);
138
0
    for (int32_t i=0; i < extraColumns; i++)
139
0
    {
140
0
      nscoord min =
141
0
        grid->GetMinRowHeight(aState, i+start, !isHorizontal); // GetMinColumnWidth
142
0
      AddWidth(minSize, min, isHorizontal);
143
0
    }
144
0
  }
145
0
146
0
  return minSize;
147
0
}
148
149
/*
150
 * Run down through our children dirtying them recursively.
151
 */
152
void
153
nsGridRowGroupLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState)
154
0
{
155
0
  if (aBox) {
156
0
    // mark us dirty
157
0
    // XXXldb We probably don't want to walk up the ancestor chain
158
0
    // calling MarkIntrinsicISizesDirty for every row group.
159
0
    aState.PresShell()->FrameNeedsReflow(aBox, nsIPresShell::eTreeChange,
160
0
                                         NS_FRAME_IS_DIRTY);
161
0
    nsIFrame* child = nsBox::GetChildXULBox(aBox);
162
0
163
0
    while(child) {
164
0
165
0
      // walk into scrollframes
166
0
      nsIFrame* deepChild = nsGrid::GetScrolledBox(child);
167
0
168
0
      // walk into other monuments
169
0
      nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild);
170
0
      if (monument)
171
0
        monument->DirtyRows(deepChild, aState);
172
0
173
0
      child = nsBox::GetNextXULBox(child);
174
0
    }
175
0
  }
176
0
}
177
178
179
void
180
nsGridRowGroupLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount)
181
0
{
182
0
  if (aBox) {
183
0
    int32_t startCount = aRowCount;
184
0
185
0
    nsIFrame* child = nsBox::GetChildXULBox(aBox);
186
0
187
0
    while(child) {
188
0
189
0
      // first see if it is a scrollframe. If so walk down into it and get the scrolled child
190
0
      nsIFrame* deepChild = nsGrid::GetScrolledBox(child);
191
0
192
0
      nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild);
193
0
      if (monument) {
194
0
        monument->CountRowsColumns(deepChild, aRowCount, aComputedColumnCount);
195
0
        child = nsBox::GetNextXULBox(child);
196
0
        deepChild = child;
197
0
        continue;
198
0
      }
199
0
200
0
      child = nsBox::GetNextXULBox(child);
201
0
202
0
      // if not a monument. Then count it. It will be a bogus row
203
0
      aRowCount++;
204
0
    }
205
0
206
0
    mRowCount = aRowCount - startCount;
207
0
  }
208
0
}
209
210
211
/**
212
 * Fill out the given row structure recursively
213
 */
214
int32_t
215
nsGridRowGroupLayout::BuildRows(nsIFrame* aBox, nsGridRow* aRows)
216
0
{
217
0
  int32_t rowCount = 0;
218
0
219
0
  if (aBox) {
220
0
    nsIFrame* child = nsBox::GetChildXULBox(aBox);
221
0
222
0
    while(child) {
223
0
224
0
      // first see if it is a scrollframe. If so walk down into it and get the scrolled child
225
0
      nsIFrame* deepChild = nsGrid::GetScrolledBox(child);
226
0
227
0
      nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild);
228
0
      if (monument) {
229
0
        rowCount += monument->BuildRows(deepChild, &aRows[rowCount]);
230
0
        child = nsBox::GetNextXULBox(child);
231
0
        deepChild = child;
232
0
        continue;
233
0
      }
234
0
235
0
      aRows[rowCount].Init(child, true);
236
0
237
0
      child = nsBox::GetNextXULBox(child);
238
0
239
0
      // if not a monument. Then count it. It will be a bogus row
240
0
      rowCount++;
241
0
    }
242
0
  }
243
0
244
0
  return rowCount;
245
0
}
246
247
nsMargin
248
nsGridRowGroupLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal)
249
0
{
250
0
  // group have border and padding added to the total margin
251
0
252
0
  nsMargin margin = nsGridRowLayout::GetTotalMargin(aBox, aIsHorizontal);
253
0
254
0
  // make sure we have the scrollframe on the outside if it has one.
255
0
  // that's where the border is.
256
0
  aBox = nsGrid::GetScrollBox(aBox);
257
0
258
0
  // add our border/padding to it
259
0
  nsMargin borderPadding(0,0,0,0);
260
0
  aBox->GetXULBorderAndPadding(borderPadding);
261
0
  margin += borderPadding;
262
0
263
0
  return margin;
264
0
}
265
266