Line data Source code
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/. */
5 :
6 : //
7 : // Eric Vaughan
8 : // Netscape Communications
9 : //
10 : // See documentation in associated header file
11 : //
12 :
13 : #include "nsGridRowLayout.h"
14 : #include "nsBoxLayoutState.h"
15 : #include "nsIScrollableFrame.h"
16 : #include "nsBox.h"
17 : #include "nsStackLayout.h"
18 : #include "nsGrid.h"
19 :
20 0 : nsGridRowLayout::nsGridRowLayout():nsSprocketLayout()
21 : {
22 0 : }
23 :
24 0 : nsGridRowLayout::~nsGridRowLayout()
25 : {
26 0 : }
27 :
28 : void
29 0 : nsGridRowLayout::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState,
30 : nsIFrame* aPrevBox,
31 : const nsFrameList::Slice& aNewChildren)
32 : {
33 0 : ChildAddedOrRemoved(aBox, aState);
34 0 : }
35 :
36 : void
37 0 : nsGridRowLayout::ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState,
38 : const nsFrameList::Slice& aNewChildren)
39 : {
40 0 : ChildAddedOrRemoved(aBox, aState);
41 0 : }
42 :
43 : void
44 0 : nsGridRowLayout::ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList)
45 : {
46 0 : ChildAddedOrRemoved(aBox, aState);
47 0 : }
48 :
49 : void
50 0 : nsGridRowLayout::ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList)
51 : {
52 0 : ChildAddedOrRemoved(aBox, aState);
53 0 : }
54 :
55 : nsIGridPart*
56 0 : nsGridRowLayout::GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox)
57 : {
58 : // go up and find our parent gridRow. Skip and non gridRow
59 : // parents.
60 0 : *aParentBox = nullptr;
61 :
62 : // walk up through any scrollboxes
63 0 : aBox = nsGrid::GetScrollBox(aBox);
64 :
65 : // get the parent
66 0 : if (aBox)
67 0 : aBox = nsBox::GetParentXULBox(aBox);
68 :
69 0 : if (aBox)
70 : {
71 0 : nsIGridPart* parentGridRow = nsGrid::GetPartFromBox(aBox);
72 0 : if (parentGridRow && parentGridRow->CanContain(this)) {
73 0 : *aParentBox = aBox;
74 0 : return parentGridRow;
75 : }
76 : }
77 :
78 0 : return nullptr;
79 : }
80 :
81 :
82 : nsGrid*
83 0 : nsGridRowLayout::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor)
84 : {
85 :
86 0 : if (aRequestor == nullptr)
87 : {
88 : nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted.
89 0 : nsIGridPart* parent = GetParentGridPart(aBox, &parentBox);
90 0 : if (parent)
91 0 : return parent->GetGrid(parentBox, aIndex, this);
92 0 : return nullptr;
93 : }
94 :
95 0 : int32_t index = -1;
96 0 : nsIFrame* child = nsBox::GetChildXULBox(aBox);
97 0 : int32_t count = 0;
98 0 : while(child)
99 : {
100 : // if there is a scrollframe walk inside it to its child
101 0 : nsIFrame* childBox = nsGrid::GetScrolledBox(child);
102 :
103 0 : nsBoxLayout* layout = childBox->GetXULLayoutManager();
104 0 : nsIGridPart* gridRow = nsGrid::GetPartFromBox(childBox);
105 0 : if (gridRow)
106 : {
107 0 : if (layout == aRequestor) {
108 0 : index = count;
109 0 : break;
110 : }
111 0 : count += gridRow->GetRowCount();
112 : } else
113 0 : count++;
114 :
115 0 : child = nsBox::GetNextXULBox(child);
116 : }
117 :
118 : // if we didn't find ourselves then the tree isn't properly formed yet
119 : // this could happen during initial construction so lets just
120 : // fail.
121 0 : if (index == -1) {
122 0 : *aIndex = -1;
123 0 : return nullptr;
124 : }
125 :
126 0 : (*aIndex) += index;
127 :
128 : nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted.
129 0 : nsIGridPart* parent = GetParentGridPart(aBox, &parentBox);
130 0 : if (parent)
131 0 : return parent->GetGrid(parentBox, aIndex, this);
132 :
133 0 : return nullptr;
134 : }
135 :
136 : nsMargin
137 0 : nsGridRowLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal)
138 : {
139 : // get our parents margin
140 0 : nsMargin margin(0,0,0,0);
141 0 : nsIFrame* parent = nullptr;
142 0 : nsIGridPart* part = GetParentGridPart(aBox, &parent);
143 0 : if (part && parent) {
144 : // if we are the first or last child walk upward and add margins.
145 :
146 : // make sure we check for a scrollbox
147 0 : aBox = nsGrid::GetScrollBox(aBox);
148 :
149 : // see if we have a next to see if we are last
150 0 : nsIFrame* next = nsBox::GetNextXULBox(aBox);
151 :
152 : // get the parent first child to see if we are first
153 0 : nsIFrame* child = nsBox::GetChildXULBox(parent);
154 :
155 0 : margin = part->GetTotalMargin(parent, aIsHorizontal);
156 :
157 : // if first or last
158 0 : if (child == aBox || next == nullptr) {
159 :
160 : // if it's not the first child remove the top margin
161 : // we don't need it.
162 0 : if (child != aBox)
163 : {
164 0 : if (aIsHorizontal)
165 0 : margin.top = 0;
166 : else
167 0 : margin.left = 0;
168 : }
169 :
170 : // if it's not the last child remove the bottom margin
171 : // we don't need it.
172 0 : if (next != nullptr)
173 : {
174 0 : if (aIsHorizontal)
175 0 : margin.bottom = 0;
176 : else
177 0 : margin.right = 0;
178 : }
179 :
180 : }
181 : }
182 :
183 : // add ours to it.
184 0 : nsMargin ourMargin;
185 0 : aBox->GetXULMargin(ourMargin);
186 0 : margin += ourMargin;
187 :
188 0 : return margin;
189 : }
190 :
191 0 : NS_IMPL_ADDREF_INHERITED(nsGridRowLayout, nsBoxLayout)
192 0 : NS_IMPL_RELEASE_INHERITED(nsGridRowLayout, nsBoxLayout)
193 :
194 0 : NS_INTERFACE_MAP_BEGIN(nsGridRowLayout)
195 0 : NS_INTERFACE_MAP_ENTRY(nsIGridPart)
196 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart)
197 0 : NS_INTERFACE_MAP_END_INHERITING(nsBoxLayout)
|