yoga-layout-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yoga/YGConfig.py +92 -0
- yoga/YGEnums.py +404 -0
- yoga/YGMacros.py +9 -0
- yoga/YGNode.py +367 -0
- yoga/YGNodeLayout.py +81 -0
- yoga/YGNodeStyle.py +876 -0
- yoga/YGPixelGrid.py +42 -0
- yoga/YGValue.py +49 -0
- yoga/__init__.py +16 -0
- yoga/algorithm/AbsoluteLayout.py +417 -0
- yoga/algorithm/Align.py +34 -0
- yoga/algorithm/Baseline.py +54 -0
- yoga/algorithm/BoundAxis.py +55 -0
- yoga/algorithm/Cache.py +93 -0
- yoga/algorithm/CalculateLayout.py +1651 -0
- yoga/algorithm/FlexDirection.py +76 -0
- yoga/algorithm/FlexLine.py +130 -0
- yoga/algorithm/PixelGrid.py +56 -0
- yoga/algorithm/SizingMode.py +39 -0
- yoga/algorithm/TrailingPosition.py +34 -0
- yoga/algorithm/__init__.py +18 -0
- yoga/config/Config.py +137 -0
- yoga/config/__init__.py +9 -0
- yoga/debug/AssertFatal.py +24 -0
- yoga/debug/Log.py +49 -0
- yoga/debug/__init__.py +10 -0
- yoga/event/__init__.py +9 -0
- yoga/event/event.py +123 -0
- yoga/node/CachedMeasurement.py +51 -0
- yoga/node/LayoutResults.py +225 -0
- yoga/node/LayoutableChildren.py +79 -0
- yoga/node/Node.py +566 -0
- yoga/node/__init__.py +11 -0
- yoga/numeric/Comparison.py +46 -0
- yoga/numeric/FloatMath.py +24 -0
- yoga/numeric/FloatOptional.py +65 -0
- yoga/numeric/__init__.py +10 -0
- yoga/style/GridLine.py +44 -0
- yoga/style/GridTrack.py +47 -0
- yoga/style/SmallValueBuffer.py +133 -0
- yoga/style/Style.py +763 -0
- yoga/style/StyleLength.py +88 -0
- yoga/style/StyleSizeLength.py +117 -0
- yoga/style/StyleValueHandle.py +98 -0
- yoga/style/StyleValuePool.py +191 -0
- yoga/style/__init__.py +16 -0
- yoga_layout_python-0.1.0.dist-info/METADATA +158 -0
- yoga_layout_python-0.1.0.dist-info/RECORD +51 -0
- yoga_layout_python-0.1.0.dist-info/WHEEL +5 -0
- yoga_layout_python-0.1.0.dist-info/licenses/LICENSE +21 -0
- yoga_layout_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1651 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
|
|
4
|
+
This source code is licensed under the MIT license found in the
|
|
5
|
+
LICENSE file in the root directory of this source tree.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from math import isnan
|
|
11
|
+
|
|
12
|
+
from ..algorithm.AbsoluteLayout import layoutAbsoluteDescendants
|
|
13
|
+
from ..algorithm.Align import fallbackAlignment, resolveChildAlignment
|
|
14
|
+
from ..algorithm.Baseline import calculateBaseline, isBaselineLayout
|
|
15
|
+
from ..algorithm.BoundAxis import boundAxis, boundAxisWithinMinAndMax, paddingAndBorderForAxis
|
|
16
|
+
from ..algorithm.Cache import canUseCachedMeasurement
|
|
17
|
+
from ..algorithm.FlexDirection import dimension, flexStartEdge, isRow, resolveCrossDirection, resolveDirection
|
|
18
|
+
from ..algorithm.FlexLine import calculateFlexLine
|
|
19
|
+
from ..algorithm.PixelGrid import roundLayoutResultsToPixelGrid
|
|
20
|
+
from ..algorithm.SizingMode import SizingMode
|
|
21
|
+
from ..algorithm.TrailingPosition import needsTrailingPosition, setChildTrailingPosition
|
|
22
|
+
from ..YGEnums import (
|
|
23
|
+
YGAlign,
|
|
24
|
+
YGDimension,
|
|
25
|
+
YGDirection,
|
|
26
|
+
YGDisplay,
|
|
27
|
+
YGEdge,
|
|
28
|
+
YGErrata,
|
|
29
|
+
YGFlexDirection,
|
|
30
|
+
YGJustify,
|
|
31
|
+
YGMeasureMode,
|
|
32
|
+
YGOverflow,
|
|
33
|
+
YGPositionType,
|
|
34
|
+
YGWrap,
|
|
35
|
+
YGExperimentalFeature,
|
|
36
|
+
)
|
|
37
|
+
from ..event.event import (
|
|
38
|
+
Event,
|
|
39
|
+
EventData,
|
|
40
|
+
LayoutData,
|
|
41
|
+
LayoutPassEndData,
|
|
42
|
+
LayoutPassReason,
|
|
43
|
+
LayoutType,
|
|
44
|
+
MeasureCallbackEndData,
|
|
45
|
+
NodeLayoutData,
|
|
46
|
+
)
|
|
47
|
+
from ..node.LayoutResults import LayoutResults
|
|
48
|
+
from ..node.Node import Node
|
|
49
|
+
from ..numeric.FloatMath import float32, floatDivision
|
|
50
|
+
from ..numeric.Comparison import inexactEquals, isDefined, isUndefined, maxOrDefined, minOrDefined
|
|
51
|
+
from ..numeric.FloatOptional import FloatOptional, maxOrDefined as maxOrDefinedFloatOptional
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
gCurrentGenerationCount = 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def constrainMaxSizeForMode(
|
|
58
|
+
node: Node,
|
|
59
|
+
direction: YGDirection,
|
|
60
|
+
axis: YGFlexDirection,
|
|
61
|
+
ownerAxisSize: float,
|
|
62
|
+
ownerWidth: float,
|
|
63
|
+
mode: SizingMode,
|
|
64
|
+
size: float,
|
|
65
|
+
) -> tuple[SizingMode, float]:
|
|
66
|
+
maxSize = node.style().resolvedMaxDimension(
|
|
67
|
+
direction,
|
|
68
|
+
YGDimension.YGDimensionWidth if isRow(axis) else YGDimension.YGDimensionHeight,
|
|
69
|
+
ownerAxisSize,
|
|
70
|
+
ownerWidth,
|
|
71
|
+
) + FloatOptional(node.style().computeMarginForAxis(axis, ownerWidth))
|
|
72
|
+
if mode in (SizingMode.StretchFit, SizingMode.FitContent):
|
|
73
|
+
size = size if maxSize.isUndefined() or size < maxSize.unwrap() else maxSize.unwrap()
|
|
74
|
+
elif mode == SizingMode.MaxContent and maxSize.isDefined():
|
|
75
|
+
mode = SizingMode.FitContent
|
|
76
|
+
size = maxSize.unwrap()
|
|
77
|
+
return mode, size
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def computeFlexBasisForChild(
|
|
81
|
+
node: Node,
|
|
82
|
+
child: Node,
|
|
83
|
+
width: float,
|
|
84
|
+
widthMode: SizingMode,
|
|
85
|
+
height: float,
|
|
86
|
+
ownerWidth: float,
|
|
87
|
+
ownerHeight: float,
|
|
88
|
+
heightMode: SizingMode,
|
|
89
|
+
direction: YGDirection,
|
|
90
|
+
layoutMarkerData: LayoutData,
|
|
91
|
+
depth: int,
|
|
92
|
+
generationCount: int,
|
|
93
|
+
) -> None:
|
|
94
|
+
mainAxis = resolveDirection(node.style().flexDirection(), direction)
|
|
95
|
+
isMainAxisRow = isRow(mainAxis)
|
|
96
|
+
mainAxisSize = width if isMainAxisRow else height
|
|
97
|
+
mainAxisOwnerSize = ownerWidth if isMainAxisRow else ownerHeight
|
|
98
|
+
childWidth = float("nan")
|
|
99
|
+
childHeight = float("nan")
|
|
100
|
+
resolvedFlexBasis = child.resolveFlexBasis(direction, mainAxis, mainAxisOwnerSize, ownerWidth)
|
|
101
|
+
isRowStyleDimDefined = child.hasDefiniteLength(YGDimension.YGDimensionWidth, ownerWidth)
|
|
102
|
+
isColumnStyleDimDefined = child.hasDefiniteLength(YGDimension.YGDimensionHeight, ownerHeight)
|
|
103
|
+
|
|
104
|
+
if resolvedFlexBasis.isDefined() and isDefined(mainAxisSize):
|
|
105
|
+
if child.getLayout().computedFlexBasis.isUndefined() or (
|
|
106
|
+
child.getConfig().isExperimentalFeatureEnabled(YGExperimentalFeature.YGExperimentalFeatureWebFlexBasis)
|
|
107
|
+
and child.getLayout().computedFlexBasisGeneration != generationCount
|
|
108
|
+
):
|
|
109
|
+
paddingAndBorder = FloatOptional(paddingAndBorderForAxis(child, mainAxis, direction, ownerWidth))
|
|
110
|
+
child.setLayoutComputedFlexBasis(
|
|
111
|
+
maxOrDefinedFloatOptional(resolvedFlexBasis, paddingAndBorder)
|
|
112
|
+
)
|
|
113
|
+
elif isMainAxisRow and isRowStyleDimDefined:
|
|
114
|
+
# The width is definite, so use that as the flex basis.
|
|
115
|
+
paddingAndBorder = FloatOptional(paddingAndBorderForAxis(child, YGFlexDirection.YGFlexDirectionRow, direction, ownerWidth))
|
|
116
|
+
child.setLayoutComputedFlexBasis(
|
|
117
|
+
FloatOptional(
|
|
118
|
+
maxOrDefined(
|
|
119
|
+
child.getResolvedDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).unwrap(),
|
|
120
|
+
paddingAndBorder.unwrap(),
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
elif (not isMainAxisRow) and isColumnStyleDimDefined:
|
|
125
|
+
# The height is definite, so use that as the flex basis.
|
|
126
|
+
paddingAndBorder = FloatOptional(paddingAndBorderForAxis(child, YGFlexDirection.YGFlexDirectionColumn, direction, ownerWidth))
|
|
127
|
+
child.setLayoutComputedFlexBasis(
|
|
128
|
+
FloatOptional(
|
|
129
|
+
maxOrDefined(
|
|
130
|
+
child.getResolvedDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).unwrap(),
|
|
131
|
+
paddingAndBorder.unwrap(),
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
else:
|
|
136
|
+
# Compute the flex basis and hypothetical main size (i.e. the clamped flex
|
|
137
|
+
# basis).
|
|
138
|
+
childWidthSizingMode = SizingMode.MaxContent
|
|
139
|
+
childHeightSizingMode = SizingMode.MaxContent
|
|
140
|
+
marginRow = child.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionRow, ownerWidth)
|
|
141
|
+
marginColumn = child.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionColumn, ownerWidth)
|
|
142
|
+
if isRowStyleDimDefined:
|
|
143
|
+
childWidth = child.getResolvedDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).unwrap() + marginRow
|
|
144
|
+
childWidthSizingMode = SizingMode.StretchFit
|
|
145
|
+
if isColumnStyleDimDefined:
|
|
146
|
+
childHeight = child.getResolvedDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).unwrap() + marginColumn
|
|
147
|
+
childHeightSizingMode = SizingMode.StretchFit
|
|
148
|
+
# The W3C spec doesn't say anything about the 'overflow' property, but all
|
|
149
|
+
# major browsers appear to implement the following logic.
|
|
150
|
+
if ((not isMainAxisRow) and node.style().overflow() == YGOverflow.YGOverflowScroll) or (
|
|
151
|
+
node.style().overflow() != YGOverflow.YGOverflowScroll
|
|
152
|
+
):
|
|
153
|
+
if isUndefined(childWidth) and isDefined(width):
|
|
154
|
+
childWidth = width
|
|
155
|
+
childWidthSizingMode = SizingMode.FitContent
|
|
156
|
+
if (isMainAxisRow and node.style().overflow() == YGOverflow.YGOverflowScroll) or (
|
|
157
|
+
node.style().overflow() != YGOverflow.YGOverflowScroll
|
|
158
|
+
):
|
|
159
|
+
if isUndefined(childHeight) and isDefined(height):
|
|
160
|
+
childHeight = height
|
|
161
|
+
childHeightSizingMode = SizingMode.FitContent
|
|
162
|
+
childStyle = child.style()
|
|
163
|
+
if childStyle.aspectRatio().isDefined():
|
|
164
|
+
if (not isMainAxisRow) and childWidthSizingMode == SizingMode.StretchFit:
|
|
165
|
+
childHeight = marginColumn + (childWidth - marginRow) / childStyle.aspectRatio().unwrap()
|
|
166
|
+
childHeightSizingMode = SizingMode.StretchFit
|
|
167
|
+
elif isMainAxisRow and childHeightSizingMode == SizingMode.StretchFit:
|
|
168
|
+
childWidth = marginRow + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap()
|
|
169
|
+
childWidthSizingMode = SizingMode.StretchFit
|
|
170
|
+
# If child has no defined size in the cross axis and is set to stretch, set
|
|
171
|
+
# the cross axis to be measured exactly with the available inner width
|
|
172
|
+
hasExactWidth = isDefined(width) and widthMode == SizingMode.StretchFit
|
|
173
|
+
childWidthStretch = resolveChildAlignment(node, child) == YGAlign.YGAlignStretch and childWidthSizingMode != SizingMode.StretchFit
|
|
174
|
+
if (not isMainAxisRow) and (not isRowStyleDimDefined) and hasExactWidth and childWidthStretch:
|
|
175
|
+
childWidth = width
|
|
176
|
+
childWidthSizingMode = SizingMode.StretchFit
|
|
177
|
+
if childStyle.aspectRatio().isDefined():
|
|
178
|
+
childHeight = (childWidth - marginRow) / childStyle.aspectRatio().unwrap()
|
|
179
|
+
childHeightSizingMode = SizingMode.StretchFit
|
|
180
|
+
hasExactHeight = isDefined(height) and heightMode == SizingMode.StretchFit
|
|
181
|
+
childHeightStretch = resolveChildAlignment(node, child) == YGAlign.YGAlignStretch and childHeightSizingMode != SizingMode.StretchFit
|
|
182
|
+
if isMainAxisRow and (not isColumnStyleDimDefined) and hasExactHeight and childHeightStretch:
|
|
183
|
+
childHeight = height
|
|
184
|
+
childHeightSizingMode = SizingMode.StretchFit
|
|
185
|
+
if childStyle.aspectRatio().isDefined():
|
|
186
|
+
childWidth = (childHeight - marginColumn) * childStyle.aspectRatio().unwrap()
|
|
187
|
+
childWidthSizingMode = SizingMode.StretchFit
|
|
188
|
+
childWidthSizingMode, childWidth = constrainMaxSizeForMode(
|
|
189
|
+
child, direction, YGFlexDirection.YGFlexDirectionRow, ownerWidth, ownerWidth, childWidthSizingMode, childWidth
|
|
190
|
+
)
|
|
191
|
+
childHeightSizingMode, childHeight = constrainMaxSizeForMode(
|
|
192
|
+
child, direction, YGFlexDirection.YGFlexDirectionColumn, ownerHeight, ownerWidth, childHeightSizingMode, childHeight
|
|
193
|
+
)
|
|
194
|
+
# Measure the child
|
|
195
|
+
calculateLayoutInternal(
|
|
196
|
+
child,
|
|
197
|
+
childWidth,
|
|
198
|
+
childHeight,
|
|
199
|
+
direction,
|
|
200
|
+
childWidthSizingMode,
|
|
201
|
+
childHeightSizingMode,
|
|
202
|
+
ownerWidth,
|
|
203
|
+
ownerHeight,
|
|
204
|
+
False,
|
|
205
|
+
LayoutPassReason.kMeasureChild,
|
|
206
|
+
layoutMarkerData,
|
|
207
|
+
depth,
|
|
208
|
+
generationCount,
|
|
209
|
+
)
|
|
210
|
+
child.setLayoutComputedFlexBasis(
|
|
211
|
+
FloatOptional(
|
|
212
|
+
maxOrDefined(
|
|
213
|
+
child.getLayout().measuredDimension(
|
|
214
|
+
YGDimension.YGDimensionWidth if isMainAxisRow else YGDimension.YGDimensionHeight
|
|
215
|
+
),
|
|
216
|
+
paddingAndBorderForAxis(child, mainAxis, direction, ownerWidth),
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
child.setLayoutComputedFlexBasisGeneration(generationCount)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def measureNodeWithMeasureFunc(
|
|
224
|
+
node: Node,
|
|
225
|
+
direction: YGDirection,
|
|
226
|
+
availableWidth: float,
|
|
227
|
+
availableHeight: float,
|
|
228
|
+
widthSizingMode: SizingMode,
|
|
229
|
+
heightSizingMode: SizingMode,
|
|
230
|
+
ownerWidth: float,
|
|
231
|
+
ownerHeight: float,
|
|
232
|
+
layoutMarkerData: LayoutData,
|
|
233
|
+
reason: LayoutPassReason,
|
|
234
|
+
) -> None:
|
|
235
|
+
if widthSizingMode == SizingMode.MaxContent:
|
|
236
|
+
availableWidth = float("nan")
|
|
237
|
+
if heightSizingMode == SizingMode.MaxContent:
|
|
238
|
+
availableHeight = float("nan")
|
|
239
|
+
layout = node.getLayout()
|
|
240
|
+
paddingAndBorderAxisRow = (
|
|
241
|
+
layout.padding(YGEdge.YGEdgeLeft)
|
|
242
|
+
+ layout.padding(YGEdge.YGEdgeRight)
|
|
243
|
+
+ layout.border(YGEdge.YGEdgeLeft)
|
|
244
|
+
+ layout.border(YGEdge.YGEdgeRight)
|
|
245
|
+
)
|
|
246
|
+
paddingAndBorderAxisColumn = (
|
|
247
|
+
layout.padding(YGEdge.YGEdgeTop)
|
|
248
|
+
+ layout.padding(YGEdge.YGEdgeBottom)
|
|
249
|
+
+ layout.border(YGEdge.YGEdgeTop)
|
|
250
|
+
+ layout.border(YGEdge.YGEdgeBottom)
|
|
251
|
+
)
|
|
252
|
+
innerWidth = availableWidth if isnan(availableWidth) else maxOrDefined(0.0, availableWidth - paddingAndBorderAxisRow)
|
|
253
|
+
innerHeight = availableHeight if isnan(availableHeight) else maxOrDefined(0.0, availableHeight - paddingAndBorderAxisColumn)
|
|
254
|
+
if widthSizingMode == SizingMode.StretchFit and heightSizingMode == SizingMode.StretchFit:
|
|
255
|
+
node.setLayoutMeasuredDimension(boundAxis(node, YGFlexDirection.YGFlexDirectionRow, direction, availableWidth, ownerWidth, ownerWidth), YGDimension.YGDimensionWidth)
|
|
256
|
+
node.setLayoutMeasuredDimension(boundAxis(node, YGFlexDirection.YGFlexDirectionColumn, direction, availableHeight, ownerHeight, ownerWidth), YGDimension.YGDimensionHeight)
|
|
257
|
+
else:
|
|
258
|
+
Event.publish(node, Event.MeasureCallbackStart, EventData())
|
|
259
|
+
measuredSize = node.measure(innerWidth, YGMeasureMode.YGMeasureModeExactly if widthSizingMode == SizingMode.StretchFit else (YGMeasureMode.YGMeasureModeAtMost if widthSizingMode == SizingMode.FitContent else YGMeasureMode.YGMeasureModeUndefined), innerHeight, YGMeasureMode.YGMeasureModeExactly if heightSizingMode == SizingMode.StretchFit else (YGMeasureMode.YGMeasureModeAtMost if heightSizingMode == SizingMode.FitContent else YGMeasureMode.YGMeasureModeUndefined))
|
|
260
|
+
layoutMarkerData.measureCallbacks += 1
|
|
261
|
+
layoutMarkerData.measureCallbackReasonsCount[int(reason)] += 1
|
|
262
|
+
Event.publish(
|
|
263
|
+
node,
|
|
264
|
+
Event.MeasureCallbackEnd,
|
|
265
|
+
MeasureCallbackEndData(
|
|
266
|
+
width=innerWidth,
|
|
267
|
+
widthMeasureMode=YGMeasureMode.YGMeasureModeExactly if widthSizingMode == SizingMode.StretchFit else (YGMeasureMode.YGMeasureModeAtMost if widthSizingMode == SizingMode.FitContent else YGMeasureMode.YGMeasureModeUndefined),
|
|
268
|
+
height=innerHeight,
|
|
269
|
+
heightMeasureMode=YGMeasureMode.YGMeasureModeExactly if heightSizingMode == SizingMode.StretchFit else (YGMeasureMode.YGMeasureModeAtMost if heightSizingMode == SizingMode.FitContent else YGMeasureMode.YGMeasureModeUndefined),
|
|
270
|
+
measuredWidth=measuredSize.width,
|
|
271
|
+
measuredHeight=measuredSize.height,
|
|
272
|
+
reason=reason,
|
|
273
|
+
),
|
|
274
|
+
)
|
|
275
|
+
node.setLayoutMeasuredDimension(
|
|
276
|
+
boundAxis(
|
|
277
|
+
node,
|
|
278
|
+
YGFlexDirection.YGFlexDirectionRow,
|
|
279
|
+
direction,
|
|
280
|
+
measuredSize.width + paddingAndBorderAxisRow if widthSizingMode in (SizingMode.MaxContent, SizingMode.FitContent) else availableWidth,
|
|
281
|
+
ownerWidth,
|
|
282
|
+
ownerWidth,
|
|
283
|
+
),
|
|
284
|
+
YGDimension.YGDimensionWidth,
|
|
285
|
+
)
|
|
286
|
+
node.setLayoutMeasuredDimension(
|
|
287
|
+
boundAxis(
|
|
288
|
+
node,
|
|
289
|
+
YGFlexDirection.YGFlexDirectionColumn,
|
|
290
|
+
direction,
|
|
291
|
+
measuredSize.height + paddingAndBorderAxisColumn if heightSizingMode in (SizingMode.MaxContent, SizingMode.FitContent) else availableHeight,
|
|
292
|
+
ownerHeight,
|
|
293
|
+
ownerWidth,
|
|
294
|
+
),
|
|
295
|
+
YGDimension.YGDimensionHeight,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def measureNodeWithoutChildren(
|
|
300
|
+
node: Node,
|
|
301
|
+
direction: YGDirection,
|
|
302
|
+
availableWidth: float,
|
|
303
|
+
availableHeight: float,
|
|
304
|
+
widthSizingMode: SizingMode,
|
|
305
|
+
heightSizingMode: SizingMode,
|
|
306
|
+
ownerWidth: float,
|
|
307
|
+
ownerHeight: float,
|
|
308
|
+
) -> None:
|
|
309
|
+
layout = node.getLayout()
|
|
310
|
+
width = availableWidth
|
|
311
|
+
if widthSizingMode in (SizingMode.MaxContent, SizingMode.FitContent):
|
|
312
|
+
width = layout.padding(YGEdge.YGEdgeLeft) + layout.padding(YGEdge.YGEdgeRight) + layout.border(YGEdge.YGEdgeLeft) + layout.border(YGEdge.YGEdgeRight)
|
|
313
|
+
node.setLayoutMeasuredDimension(boundAxis(node, YGFlexDirection.YGFlexDirectionRow, direction, width, ownerWidth, ownerWidth), YGDimension.YGDimensionWidth)
|
|
314
|
+
height = availableHeight
|
|
315
|
+
if heightSizingMode in (SizingMode.MaxContent, SizingMode.FitContent):
|
|
316
|
+
height = layout.padding(YGEdge.YGEdgeTop) + layout.padding(YGEdge.YGEdgeBottom) + layout.border(YGEdge.YGEdgeTop) + layout.border(YGEdge.YGEdgeBottom)
|
|
317
|
+
node.setLayoutMeasuredDimension(boundAxis(node, YGFlexDirection.YGFlexDirectionColumn, direction, height, ownerHeight, ownerWidth), YGDimension.YGDimensionHeight)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def isFixedSize(dim: float, sizingMode: SizingMode) -> bool:
|
|
321
|
+
return sizingMode == SizingMode.StretchFit or (dim == dim and sizingMode == SizingMode.FitContent and dim <= 0.0)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def measureNodeWithFixedSize(
|
|
325
|
+
node: Node,
|
|
326
|
+
direction: YGDirection,
|
|
327
|
+
availableWidth: float,
|
|
328
|
+
availableHeight: float,
|
|
329
|
+
widthSizingMode: SizingMode,
|
|
330
|
+
heightSizingMode: SizingMode,
|
|
331
|
+
ownerWidth: float,
|
|
332
|
+
ownerHeight: float,
|
|
333
|
+
) -> bool:
|
|
334
|
+
if isFixedSize(availableWidth, widthSizingMode) and isFixedSize(availableHeight, heightSizingMode):
|
|
335
|
+
node.setLayoutMeasuredDimension(boundAxis(node, YGFlexDirection.YGFlexDirectionRow, direction, 0.0 if isnan(availableWidth) or (widthSizingMode == SizingMode.FitContent and availableWidth < 0.0) else availableWidth, ownerWidth, ownerWidth), YGDimension.YGDimensionWidth)
|
|
336
|
+
node.setLayoutMeasuredDimension(boundAxis(node, YGFlexDirection.YGFlexDirectionColumn, direction, 0.0 if isnan(availableHeight) or (heightSizingMode == SizingMode.FitContent and availableHeight < 0.0) else availableHeight, ownerHeight, ownerWidth), YGDimension.YGDimensionHeight)
|
|
337
|
+
return True
|
|
338
|
+
return False
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def zeroOutLayoutRecursively(node: Node) -> None:
|
|
342
|
+
node.setLayout(LayoutResults())
|
|
343
|
+
node.setLayoutDimension(0, YGDimension.YGDimensionWidth)
|
|
344
|
+
node.setLayoutDimension(0, YGDimension.YGDimensionHeight)
|
|
345
|
+
node.setHasNewLayout(True)
|
|
346
|
+
node.cloneChildrenIfNeeded()
|
|
347
|
+
for child in node.getChildren():
|
|
348
|
+
zeroOutLayoutRecursively(child)
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def cleanupContentsNodesRecursively(node: Node) -> None:
|
|
352
|
+
if node.hasContentsChildren():
|
|
353
|
+
node.cloneContentsChildrenIfNeeded()
|
|
354
|
+
for child in node.getChildren():
|
|
355
|
+
if child.style().display().name.endswith("Contents"):
|
|
356
|
+
child.setLayout(LayoutResults())
|
|
357
|
+
child.setLayoutDimension(0, YGDimension.YGDimensionWidth)
|
|
358
|
+
child.setLayoutDimension(0, YGDimension.YGDimensionHeight)
|
|
359
|
+
child.setHasNewLayout(True)
|
|
360
|
+
child.setDirty(False)
|
|
361
|
+
child.cloneChildrenIfNeeded()
|
|
362
|
+
cleanupContentsNodesRecursively(child)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def calculateAvailableInnerDimension(
|
|
366
|
+
node: Node,
|
|
367
|
+
direction: YGDirection,
|
|
368
|
+
dimensionValue: YGDimension,
|
|
369
|
+
availableDim: float,
|
|
370
|
+
paddingAndBorder: float,
|
|
371
|
+
ownerDim: float,
|
|
372
|
+
ownerWidth: float,
|
|
373
|
+
) -> float:
|
|
374
|
+
availableInnerDim = availableDim - paddingAndBorder
|
|
375
|
+
if availableInnerDim == availableInnerDim:
|
|
376
|
+
minDimensionOptional = node.style().resolvedMinDimension(direction, dimensionValue, ownerDim, ownerWidth)
|
|
377
|
+
minInnerDim = 0.0 if minDimensionOptional.isUndefined() else minDimensionOptional.unwrap() - paddingAndBorder
|
|
378
|
+
maxDimensionOptional = node.style().resolvedMaxDimension(direction, dimensionValue, ownerDim, ownerWidth)
|
|
379
|
+
maxInnerDim = float("inf") if maxDimensionOptional.isUndefined() else maxDimensionOptional.unwrap() - paddingAndBorder
|
|
380
|
+
availableInnerDim = maxOrDefined(min(availableInnerDim, maxInnerDim), minInnerDim)
|
|
381
|
+
return availableInnerDim
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def computeFlexBasisForChildren(
|
|
385
|
+
node: Node,
|
|
386
|
+
availableInnerWidth: float,
|
|
387
|
+
availableInnerHeight: float,
|
|
388
|
+
widthSizingMode: SizingMode,
|
|
389
|
+
heightSizingMode: SizingMode,
|
|
390
|
+
direction: YGDirection,
|
|
391
|
+
mainAxis: YGFlexDirection,
|
|
392
|
+
performLayout: bool,
|
|
393
|
+
layoutMarkerData: LayoutData,
|
|
394
|
+
depth: int,
|
|
395
|
+
generationCount: int,
|
|
396
|
+
) -> float:
|
|
397
|
+
totalOuterFlexBasis = float32(0.0)
|
|
398
|
+
singleFlexChild = None
|
|
399
|
+
children = list(node.getLayoutChildren())
|
|
400
|
+
sizingModeMainDim = widthSizingMode if isRow(mainAxis) else heightSizingMode
|
|
401
|
+
if sizingModeMainDim == SizingMode.StretchFit:
|
|
402
|
+
for child in children:
|
|
403
|
+
if child.isNodeFlexible():
|
|
404
|
+
if singleFlexChild is not None or child.resolveFlexGrow() == 0.0 or child.resolveFlexShrink() == 0.0:
|
|
405
|
+
singleFlexChild = None
|
|
406
|
+
break
|
|
407
|
+
singleFlexChild = child
|
|
408
|
+
for child in children:
|
|
409
|
+
child.processDimensions()
|
|
410
|
+
if child.style().display().name.endswith("None"):
|
|
411
|
+
zeroOutLayoutRecursively(child)
|
|
412
|
+
child.setHasNewLayout(True)
|
|
413
|
+
child.setDirty(False)
|
|
414
|
+
continue
|
|
415
|
+
if performLayout:
|
|
416
|
+
childDirection = child.resolveDirection(direction)
|
|
417
|
+
child.setPosition(childDirection, availableInnerWidth, availableInnerHeight)
|
|
418
|
+
if child.style().positionType().name.endswith("Absolute"):
|
|
419
|
+
continue
|
|
420
|
+
if child == singleFlexChild:
|
|
421
|
+
child.setLayoutComputedFlexBasisGeneration(generationCount)
|
|
422
|
+
child.setLayoutComputedFlexBasis(FloatOptional(0.0))
|
|
423
|
+
else:
|
|
424
|
+
computeFlexBasisForChild(
|
|
425
|
+
node,
|
|
426
|
+
child,
|
|
427
|
+
availableInnerWidth,
|
|
428
|
+
widthSizingMode,
|
|
429
|
+
availableInnerHeight,
|
|
430
|
+
availableInnerWidth,
|
|
431
|
+
availableInnerHeight,
|
|
432
|
+
heightSizingMode,
|
|
433
|
+
direction,
|
|
434
|
+
layoutMarkerData,
|
|
435
|
+
depth,
|
|
436
|
+
generationCount,
|
|
437
|
+
)
|
|
438
|
+
totalOuterFlexBasis = float32(
|
|
439
|
+
totalOuterFlexBasis
|
|
440
|
+
+ float32(
|
|
441
|
+
child.getLayout().computedFlexBasis.unwrap()
|
|
442
|
+
+ child.style().computeMarginForAxis(mainAxis, availableInnerWidth)
|
|
443
|
+
)
|
|
444
|
+
)
|
|
445
|
+
return totalOuterFlexBasis
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def distributeFreeSpaceFirstPass(
|
|
449
|
+
flexLine,
|
|
450
|
+
direction: YGDirection,
|
|
451
|
+
mainAxis: YGFlexDirection,
|
|
452
|
+
ownerWidth: float,
|
|
453
|
+
mainAxisOwnerSize: float,
|
|
454
|
+
availableInnerMainDim: float,
|
|
455
|
+
availableInnerWidth: float,
|
|
456
|
+
) -> None:
|
|
457
|
+
deltaFreeSpace = float32(0.0)
|
|
458
|
+
for currentLineChild in flexLine.itemsInFlow:
|
|
459
|
+
childFlexBasis = float32(
|
|
460
|
+
boundAxisWithinMinAndMax(
|
|
461
|
+
currentLineChild,
|
|
462
|
+
direction,
|
|
463
|
+
mainAxis,
|
|
464
|
+
currentLineChild.getLayout().computedFlexBasis,
|
|
465
|
+
mainAxisOwnerSize,
|
|
466
|
+
ownerWidth,
|
|
467
|
+
).unwrap()
|
|
468
|
+
)
|
|
469
|
+
if flexLine.layout.remainingFreeSpace < 0:
|
|
470
|
+
flexShrinkScaledFactor = float32(
|
|
471
|
+
-currentLineChild.resolveFlexShrink() * childFlexBasis
|
|
472
|
+
)
|
|
473
|
+
if flexShrinkScaledFactor == flexShrinkScaledFactor and flexShrinkScaledFactor != 0:
|
|
474
|
+
shrinkRatio = float32(
|
|
475
|
+
floatDivision(
|
|
476
|
+
flexLine.layout.remainingFreeSpace,
|
|
477
|
+
flexLine.layout.totalFlexShrinkScaledFactors,
|
|
478
|
+
)
|
|
479
|
+
)
|
|
480
|
+
baseMainSize = float32(
|
|
481
|
+
childFlexBasis
|
|
482
|
+
+ float32(shrinkRatio * flexShrinkScaledFactor)
|
|
483
|
+
)
|
|
484
|
+
boundMainSize = boundAxis(currentLineChild, mainAxis, direction, baseMainSize, availableInnerMainDim, availableInnerWidth)
|
|
485
|
+
if baseMainSize == baseMainSize and boundMainSize == boundMainSize and baseMainSize != boundMainSize:
|
|
486
|
+
deltaFreeSpace = float32(
|
|
487
|
+
deltaFreeSpace + float32(boundMainSize - childFlexBasis)
|
|
488
|
+
)
|
|
489
|
+
flexLine.layout.totalFlexShrinkScaledFactors = float32(
|
|
490
|
+
flexLine.layout.totalFlexShrinkScaledFactors
|
|
491
|
+
- float32(
|
|
492
|
+
-currentLineChild.resolveFlexShrink()
|
|
493
|
+
* currentLineChild.getLayout().computedFlexBasis.unwrap()
|
|
494
|
+
)
|
|
495
|
+
)
|
|
496
|
+
elif flexLine.layout.remainingFreeSpace == flexLine.layout.remainingFreeSpace and flexLine.layout.remainingFreeSpace > 0:
|
|
497
|
+
flexGrowFactor = currentLineChild.resolveFlexGrow()
|
|
498
|
+
if flexGrowFactor == flexGrowFactor and flexGrowFactor != 0:
|
|
499
|
+
growRatio = float32(
|
|
500
|
+
floatDivision(
|
|
501
|
+
flexLine.layout.remainingFreeSpace,
|
|
502
|
+
flexLine.layout.totalFlexGrowFactors,
|
|
503
|
+
)
|
|
504
|
+
)
|
|
505
|
+
baseMainSize = float32(
|
|
506
|
+
childFlexBasis
|
|
507
|
+
+ float32(growRatio * flexGrowFactor)
|
|
508
|
+
)
|
|
509
|
+
boundMainSize = boundAxis(currentLineChild, mainAxis, direction, baseMainSize, availableInnerMainDim, availableInnerWidth)
|
|
510
|
+
if baseMainSize == baseMainSize and boundMainSize == boundMainSize and baseMainSize != boundMainSize:
|
|
511
|
+
deltaFreeSpace = float32(
|
|
512
|
+
deltaFreeSpace + float32(boundMainSize - childFlexBasis)
|
|
513
|
+
)
|
|
514
|
+
flexLine.layout.totalFlexGrowFactors = float32(
|
|
515
|
+
flexLine.layout.totalFlexGrowFactors - flexGrowFactor
|
|
516
|
+
)
|
|
517
|
+
flexLine.layout.remainingFreeSpace = float32(
|
|
518
|
+
flexLine.layout.remainingFreeSpace - deltaFreeSpace
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def distributeFreeSpaceSecondPass(
|
|
523
|
+
flexLine,
|
|
524
|
+
node: Node,
|
|
525
|
+
mainAxis: YGFlexDirection,
|
|
526
|
+
crossAxis: YGFlexDirection,
|
|
527
|
+
direction: YGDirection,
|
|
528
|
+
ownerWidth: float,
|
|
529
|
+
mainAxisOwnerSize: float,
|
|
530
|
+
availableInnerMainDim: float,
|
|
531
|
+
availableInnerCrossDim: float,
|
|
532
|
+
availableInnerWidth: float,
|
|
533
|
+
availableInnerHeight: float,
|
|
534
|
+
mainAxisOverflows: bool,
|
|
535
|
+
sizingModeCrossDim: SizingMode,
|
|
536
|
+
performLayout: bool,
|
|
537
|
+
layoutMarkerData: LayoutData,
|
|
538
|
+
depth: int,
|
|
539
|
+
generationCount: int,
|
|
540
|
+
) -> float:
|
|
541
|
+
deltaFreeSpace = float32(0.0)
|
|
542
|
+
isMainAxisRow = isRow(mainAxis)
|
|
543
|
+
isNodeFlexWrap = node.style().flexWrap() != getattr(node.style().flexWrap().__class__, "YGWrapNoWrap", node.style().flexWrap())
|
|
544
|
+
for currentLineChild in flexLine.itemsInFlow:
|
|
545
|
+
childFlexBasis = float32(
|
|
546
|
+
boundAxisWithinMinAndMax(
|
|
547
|
+
currentLineChild,
|
|
548
|
+
direction,
|
|
549
|
+
mainAxis,
|
|
550
|
+
currentLineChild.getLayout().computedFlexBasis,
|
|
551
|
+
mainAxisOwnerSize,
|
|
552
|
+
ownerWidth,
|
|
553
|
+
).unwrap()
|
|
554
|
+
)
|
|
555
|
+
updatedMainSize = childFlexBasis
|
|
556
|
+
if flexLine.layout.remainingFreeSpace == flexLine.layout.remainingFreeSpace and flexLine.layout.remainingFreeSpace < 0:
|
|
557
|
+
flexShrinkScaledFactor = float32(
|
|
558
|
+
-currentLineChild.resolveFlexShrink() * childFlexBasis
|
|
559
|
+
)
|
|
560
|
+
if flexShrinkScaledFactor != 0:
|
|
561
|
+
if flexLine.layout.totalFlexShrinkScaledFactors == 0:
|
|
562
|
+
childSize = float32(childFlexBasis + flexShrinkScaledFactor)
|
|
563
|
+
else:
|
|
564
|
+
shrinkRatio = float32(
|
|
565
|
+
floatDivision(
|
|
566
|
+
flexLine.layout.remainingFreeSpace,
|
|
567
|
+
flexLine.layout.totalFlexShrinkScaledFactors,
|
|
568
|
+
)
|
|
569
|
+
)
|
|
570
|
+
childSize = float32(
|
|
571
|
+
childFlexBasis
|
|
572
|
+
+ float32(shrinkRatio * flexShrinkScaledFactor)
|
|
573
|
+
)
|
|
574
|
+
updatedMainSize = float32(
|
|
575
|
+
boundAxis(
|
|
576
|
+
currentLineChild,
|
|
577
|
+
mainAxis,
|
|
578
|
+
direction,
|
|
579
|
+
childSize,
|
|
580
|
+
availableInnerMainDim,
|
|
581
|
+
availableInnerWidth,
|
|
582
|
+
)
|
|
583
|
+
)
|
|
584
|
+
elif flexLine.layout.remainingFreeSpace == flexLine.layout.remainingFreeSpace and flexLine.layout.remainingFreeSpace > 0:
|
|
585
|
+
flexGrowFactor = currentLineChild.resolveFlexGrow()
|
|
586
|
+
if flexGrowFactor == flexGrowFactor and flexGrowFactor != 0:
|
|
587
|
+
growRatio = float32(
|
|
588
|
+
floatDivision(
|
|
589
|
+
flexLine.layout.remainingFreeSpace,
|
|
590
|
+
flexLine.layout.totalFlexGrowFactors,
|
|
591
|
+
)
|
|
592
|
+
)
|
|
593
|
+
updatedMainSize = float32(
|
|
594
|
+
boundAxis(
|
|
595
|
+
currentLineChild,
|
|
596
|
+
mainAxis,
|
|
597
|
+
direction,
|
|
598
|
+
float32(
|
|
599
|
+
childFlexBasis
|
|
600
|
+
+ float32(growRatio * flexGrowFactor)
|
|
601
|
+
),
|
|
602
|
+
availableInnerMainDim,
|
|
603
|
+
availableInnerWidth,
|
|
604
|
+
)
|
|
605
|
+
)
|
|
606
|
+
deltaFreeSpace = float32(
|
|
607
|
+
deltaFreeSpace + float32(updatedMainSize - childFlexBasis)
|
|
608
|
+
)
|
|
609
|
+
marginMain = currentLineChild.style().computeMarginForAxis(mainAxis, availableInnerWidth)
|
|
610
|
+
marginCross = currentLineChild.style().computeMarginForAxis(crossAxis, availableInnerWidth)
|
|
611
|
+
childCrossSize = float("nan")
|
|
612
|
+
childMainSize = updatedMainSize + marginMain
|
|
613
|
+
childStyle = currentLineChild.style()
|
|
614
|
+
childMainSizingMode = SizingMode.StretchFit
|
|
615
|
+
if childStyle.aspectRatio().isDefined():
|
|
616
|
+
childCrossSize = (
|
|
617
|
+
(childMainSize - marginMain) / childStyle.aspectRatio().unwrap()
|
|
618
|
+
if isMainAxisRow
|
|
619
|
+
else (childMainSize - marginMain) * childStyle.aspectRatio().unwrap()
|
|
620
|
+
)
|
|
621
|
+
childCrossSizingMode = SizingMode.StretchFit
|
|
622
|
+
childCrossSize += marginCross
|
|
623
|
+
elif (
|
|
624
|
+
availableInnerCrossDim == availableInnerCrossDim
|
|
625
|
+
and not currentLineChild.hasDefiniteLength(
|
|
626
|
+
YGDimension.YGDimensionHeight if isMainAxisRow else YGDimension.YGDimensionWidth,
|
|
627
|
+
availableInnerCrossDim,
|
|
628
|
+
)
|
|
629
|
+
and sizingModeCrossDim == SizingMode.StretchFit
|
|
630
|
+
and not (isNodeFlexWrap and mainAxisOverflows)
|
|
631
|
+
and resolveChildAlignment(node, currentLineChild) == YGAlign.YGAlignStretch
|
|
632
|
+
and not currentLineChild.style().flexStartMarginIsAuto(crossAxis, direction)
|
|
633
|
+
and not currentLineChild.style().flexEndMarginIsAuto(crossAxis, direction)
|
|
634
|
+
):
|
|
635
|
+
childCrossSize = availableInnerCrossDim
|
|
636
|
+
childCrossSizingMode = SizingMode.StretchFit
|
|
637
|
+
elif not currentLineChild.hasDefiniteLength(
|
|
638
|
+
YGDimension.YGDimensionHeight if isMainAxisRow else YGDimension.YGDimensionWidth,
|
|
639
|
+
availableInnerCrossDim,
|
|
640
|
+
):
|
|
641
|
+
childCrossSize = availableInnerCrossDim
|
|
642
|
+
childCrossSizingMode = SizingMode.MaxContent if isnan(childCrossSize) else SizingMode.FitContent
|
|
643
|
+
else:
|
|
644
|
+
childCrossSize = currentLineChild.getResolvedDimension(
|
|
645
|
+
direction,
|
|
646
|
+
YGDimension.YGDimensionHeight if isMainAxisRow else YGDimension.YGDimensionWidth,
|
|
647
|
+
availableInnerCrossDim,
|
|
648
|
+
availableInnerWidth,
|
|
649
|
+
).unwrap() + marginCross
|
|
650
|
+
isLoosePercentageMeasurement = (
|
|
651
|
+
currentLineChild.getProcessedDimension(
|
|
652
|
+
YGDimension.YGDimensionHeight if isMainAxisRow else YGDimension.YGDimensionWidth
|
|
653
|
+
).isPercent()
|
|
654
|
+
and sizingModeCrossDim != SizingMode.StretchFit
|
|
655
|
+
)
|
|
656
|
+
childCrossSizingMode = (
|
|
657
|
+
SizingMode.MaxContent
|
|
658
|
+
if isnan(childCrossSize) or isLoosePercentageMeasurement
|
|
659
|
+
else SizingMode.StretchFit
|
|
660
|
+
)
|
|
661
|
+
childMainSizingMode, childMainSize = constrainMaxSizeForMode(currentLineChild, direction, mainAxis, availableInnerMainDim, availableInnerWidth, childMainSizingMode, childMainSize)
|
|
662
|
+
childCrossSizingMode, childCrossSize = constrainMaxSizeForMode(currentLineChild, direction, crossAxis, availableInnerCrossDim, availableInnerWidth, childCrossSizingMode, childCrossSize)
|
|
663
|
+
requiresStretchLayout = (
|
|
664
|
+
not currentLineChild.hasDefiniteLength(YGDimension.YGDimensionHeight if isMainAxisRow else YGDimension.YGDimensionWidth, availableInnerCrossDim)
|
|
665
|
+
and resolveChildAlignment(node, currentLineChild) == YGAlign.YGAlignStretch
|
|
666
|
+
and not currentLineChild.style().flexStartMarginIsAuto(crossAxis, direction)
|
|
667
|
+
and not currentLineChild.style().flexEndMarginIsAuto(crossAxis, direction)
|
|
668
|
+
)
|
|
669
|
+
childWidth = childMainSize if isMainAxisRow else childCrossSize
|
|
670
|
+
childHeight = childMainSize if not isMainAxisRow else childCrossSize
|
|
671
|
+
childWidthSizingMode = childMainSizingMode if isMainAxisRow else childCrossSizingMode
|
|
672
|
+
childHeightSizingMode = childMainSizingMode if not isMainAxisRow else childCrossSizingMode
|
|
673
|
+
isLayoutPass = performLayout and not requiresStretchLayout
|
|
674
|
+
calculateLayoutInternal(
|
|
675
|
+
currentLineChild,
|
|
676
|
+
childWidth,
|
|
677
|
+
childHeight,
|
|
678
|
+
node.getLayout().direction(),
|
|
679
|
+
childWidthSizingMode,
|
|
680
|
+
childHeightSizingMode,
|
|
681
|
+
availableInnerWidth,
|
|
682
|
+
availableInnerHeight,
|
|
683
|
+
isLayoutPass,
|
|
684
|
+
LayoutPassReason.kFlexLayout if isLayoutPass else LayoutPassReason.kFlexMeasure,
|
|
685
|
+
layoutMarkerData,
|
|
686
|
+
depth,
|
|
687
|
+
generationCount,
|
|
688
|
+
)
|
|
689
|
+
node.setLayoutHadOverflow(node.getLayout().hadOverflow() or currentLineChild.getLayout().hadOverflow())
|
|
690
|
+
return deltaFreeSpace
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
def resolveFlexibleLength(
|
|
694
|
+
node: Node,
|
|
695
|
+
flexLine,
|
|
696
|
+
mainAxis: YGFlexDirection,
|
|
697
|
+
crossAxis: YGFlexDirection,
|
|
698
|
+
direction: YGDirection,
|
|
699
|
+
ownerWidth: float,
|
|
700
|
+
mainAxisOwnerSize: float,
|
|
701
|
+
availableInnerMainDim: float,
|
|
702
|
+
availableInnerCrossDim: float,
|
|
703
|
+
availableInnerWidth: float,
|
|
704
|
+
availableInnerHeight: float,
|
|
705
|
+
mainAxisOverflows: bool,
|
|
706
|
+
sizingModeCrossDim: SizingMode,
|
|
707
|
+
performLayout: bool,
|
|
708
|
+
layoutMarkerData: LayoutData,
|
|
709
|
+
depth: int,
|
|
710
|
+
generationCount: int,
|
|
711
|
+
) -> None:
|
|
712
|
+
originalFreeSpace = flexLine.layout.remainingFreeSpace
|
|
713
|
+
distributeFreeSpaceFirstPass(
|
|
714
|
+
flexLine,
|
|
715
|
+
direction,
|
|
716
|
+
mainAxis,
|
|
717
|
+
ownerWidth,
|
|
718
|
+
mainAxisOwnerSize,
|
|
719
|
+
availableInnerMainDim,
|
|
720
|
+
availableInnerWidth,
|
|
721
|
+
)
|
|
722
|
+
distributedFreeSpace = distributeFreeSpaceSecondPass(
|
|
723
|
+
flexLine,
|
|
724
|
+
node,
|
|
725
|
+
mainAxis,
|
|
726
|
+
crossAxis,
|
|
727
|
+
direction,
|
|
728
|
+
ownerWidth,
|
|
729
|
+
mainAxisOwnerSize,
|
|
730
|
+
availableInnerMainDim,
|
|
731
|
+
availableInnerCrossDim,
|
|
732
|
+
availableInnerWidth,
|
|
733
|
+
availableInnerHeight,
|
|
734
|
+
mainAxisOverflows,
|
|
735
|
+
sizingModeCrossDim,
|
|
736
|
+
performLayout,
|
|
737
|
+
layoutMarkerData,
|
|
738
|
+
depth,
|
|
739
|
+
generationCount,
|
|
740
|
+
)
|
|
741
|
+
flexLine.layout.remainingFreeSpace = float32(
|
|
742
|
+
originalFreeSpace - distributedFreeSpace
|
|
743
|
+
)
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
def justifyMainAxis(
|
|
747
|
+
node: Node,
|
|
748
|
+
flexLine,
|
|
749
|
+
mainAxis: YGFlexDirection,
|
|
750
|
+
crossAxis: YGFlexDirection,
|
|
751
|
+
direction: YGDirection,
|
|
752
|
+
sizingModeMainDim: SizingMode,
|
|
753
|
+
sizingModeCrossDim: SizingMode,
|
|
754
|
+
mainAxisOwnerSize: float,
|
|
755
|
+
ownerWidth: float,
|
|
756
|
+
availableInnerMainDim: float,
|
|
757
|
+
availableInnerCrossDim: float,
|
|
758
|
+
availableInnerWidth: float,
|
|
759
|
+
performLayout: bool,
|
|
760
|
+
) -> None:
|
|
761
|
+
style = node.style()
|
|
762
|
+
leadingPaddingAndBorderMain = style.computeFlexStartPaddingAndBorder(mainAxis, direction, ownerWidth)
|
|
763
|
+
trailingPaddingAndBorderMain = style.computeFlexEndPaddingAndBorder(mainAxis, direction, ownerWidth)
|
|
764
|
+
gap = style.computeGapForAxis(mainAxis, availableInnerMainDim)
|
|
765
|
+
if sizingModeMainDim == SizingMode.FitContent and flexLine.layout.remainingFreeSpace > 0:
|
|
766
|
+
if style.minDimension(dimension(mainAxis)).isDefined() and style.resolvedMinDimension(
|
|
767
|
+
direction, dimension(mainAxis), mainAxisOwnerSize, ownerWidth
|
|
768
|
+
).isDefined():
|
|
769
|
+
minAvailableMainDim = (
|
|
770
|
+
style.resolvedMinDimension(direction, dimension(mainAxis), mainAxisOwnerSize, ownerWidth).unwrap()
|
|
771
|
+
- leadingPaddingAndBorderMain
|
|
772
|
+
- trailingPaddingAndBorderMain
|
|
773
|
+
)
|
|
774
|
+
occupiedSpaceByChildNodes = availableInnerMainDim - flexLine.layout.remainingFreeSpace
|
|
775
|
+
flexLine.layout.remainingFreeSpace = maxOrDefined(0.0, minAvailableMainDim - occupiedSpaceByChildNodes)
|
|
776
|
+
else:
|
|
777
|
+
flexLine.layout.remainingFreeSpace = 0.0
|
|
778
|
+
leadingMainDim = 0.0
|
|
779
|
+
betweenMainDim = gap
|
|
780
|
+
justifyContent = (
|
|
781
|
+
node.style().justifyContent()
|
|
782
|
+
if flexLine.layout.remainingFreeSpace >= 0
|
|
783
|
+
else fallbackAlignment(node.style().justifyContent())
|
|
784
|
+
)
|
|
785
|
+
if flexLine.numberOfAutoMargins == 0:
|
|
786
|
+
if justifyContent == YGJustify.YGJustifyCenter:
|
|
787
|
+
leadingMainDim = flexLine.layout.remainingFreeSpace / 2
|
|
788
|
+
elif justifyContent == YGJustify.YGJustifyFlexEnd:
|
|
789
|
+
leadingMainDim = flexLine.layout.remainingFreeSpace
|
|
790
|
+
elif justifyContent == YGJustify.YGJustifySpaceBetween:
|
|
791
|
+
if len(flexLine.itemsInFlow) > 1:
|
|
792
|
+
betweenMainDim += flexLine.layout.remainingFreeSpace / float(len(flexLine.itemsInFlow) - 1)
|
|
793
|
+
elif justifyContent == YGJustify.YGJustifySpaceEvenly:
|
|
794
|
+
leadingMainDim = floatDivision(
|
|
795
|
+
flexLine.layout.remainingFreeSpace,
|
|
796
|
+
float(len(flexLine.itemsInFlow) + 1),
|
|
797
|
+
)
|
|
798
|
+
betweenMainDim += leadingMainDim
|
|
799
|
+
elif justifyContent == YGJustify.YGJustifySpaceAround:
|
|
800
|
+
leadingMainDim = 0.5 * floatDivision(
|
|
801
|
+
flexLine.layout.remainingFreeSpace,
|
|
802
|
+
float(len(flexLine.itemsInFlow)),
|
|
803
|
+
)
|
|
804
|
+
betweenMainDim += leadingMainDim * 2
|
|
805
|
+
flexLine.layout.mainDim = leadingPaddingAndBorderMain + leadingMainDim
|
|
806
|
+
flexLine.layout.crossDim = 0.0
|
|
807
|
+
maxAscentForCurrentLine = 0.0
|
|
808
|
+
maxDescentForCurrentLine = 0.0
|
|
809
|
+
nodeBaselineLayout = isBaselineLayout(node)
|
|
810
|
+
for child in flexLine.itemsInFlow:
|
|
811
|
+
childLayout = child.getLayout()
|
|
812
|
+
if child.style().flexStartMarginIsAuto(mainAxis, direction) and flexLine.layout.remainingFreeSpace > 0.0:
|
|
813
|
+
flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / float(flexLine.numberOfAutoMargins)
|
|
814
|
+
if performLayout:
|
|
815
|
+
child.setLayoutPosition(
|
|
816
|
+
childLayout.position(flexStartEdge(mainAxis)) + flexLine.layout.mainDim,
|
|
817
|
+
flexStartEdge(mainAxis),
|
|
818
|
+
)
|
|
819
|
+
if child is not flexLine.itemsInFlow[-1]:
|
|
820
|
+
flexLine.layout.mainDim += betweenMainDim
|
|
821
|
+
if child.style().flexEndMarginIsAuto(mainAxis, direction) and flexLine.layout.remainingFreeSpace > 0.0:
|
|
822
|
+
flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / float(flexLine.numberOfAutoMargins)
|
|
823
|
+
canSkipFlex = (not performLayout) and sizingModeCrossDim == SizingMode.StretchFit
|
|
824
|
+
if canSkipFlex:
|
|
825
|
+
flexLine.layout.mainDim = float32(
|
|
826
|
+
flexLine.layout.mainDim
|
|
827
|
+
+ child.style().computeMarginForAxis(mainAxis, availableInnerWidth)
|
|
828
|
+
+ childLayout.computedFlexBasis.unwrap()
|
|
829
|
+
)
|
|
830
|
+
flexLine.layout.crossDim = availableInnerCrossDim
|
|
831
|
+
else:
|
|
832
|
+
flexLine.layout.mainDim += child.dimensionWithMargin(mainAxis, availableInnerWidth)
|
|
833
|
+
if nodeBaselineLayout:
|
|
834
|
+
ascent = calculateBaseline(child) + child.style().computeFlexStartMargin(
|
|
835
|
+
YGFlexDirection.YGFlexDirectionColumn, direction, availableInnerWidth
|
|
836
|
+
)
|
|
837
|
+
descent = (
|
|
838
|
+
child.getLayout().measuredDimension(YGDimension.YGDimensionHeight)
|
|
839
|
+
+ child.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionColumn, availableInnerWidth)
|
|
840
|
+
- ascent
|
|
841
|
+
)
|
|
842
|
+
maxAscentForCurrentLine = maxOrDefined(maxAscentForCurrentLine, ascent)
|
|
843
|
+
maxDescentForCurrentLine = maxOrDefined(maxDescentForCurrentLine, descent)
|
|
844
|
+
else:
|
|
845
|
+
flexLine.layout.crossDim = maxOrDefined(
|
|
846
|
+
flexLine.layout.crossDim, child.dimensionWithMargin(crossAxis, availableInnerWidth)
|
|
847
|
+
)
|
|
848
|
+
flexLine.layout.mainDim += trailingPaddingAndBorderMain
|
|
849
|
+
if nodeBaselineLayout:
|
|
850
|
+
flexLine.layout.crossDim = maxAscentForCurrentLine + maxDescentForCurrentLine
|
|
851
|
+
def calculateLayout(node: Node, ownerWidth: float, ownerHeight: float, ownerDirection: YGDirection) -> None:
|
|
852
|
+
global gCurrentGenerationCount
|
|
853
|
+
Event.publish(node, Event.LayoutPassStart, EventData())
|
|
854
|
+
layoutMarkerData = LayoutData()
|
|
855
|
+
gCurrentGenerationCount += 1
|
|
856
|
+
node.processDimensions()
|
|
857
|
+
direction = node.resolveDirection(ownerDirection)
|
|
858
|
+
style = node.style()
|
|
859
|
+
width = float("nan")
|
|
860
|
+
widthSizingMode = SizingMode.MaxContent
|
|
861
|
+
if node.hasDefiniteLength(YGDimension.YGDimensionWidth, ownerWidth):
|
|
862
|
+
width = node.getResolvedDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).unwrap() + node.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionRow, ownerWidth)
|
|
863
|
+
widthSizingMode = SizingMode.StretchFit
|
|
864
|
+
elif style.resolvedMaxDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).isDefined():
|
|
865
|
+
width = style.resolvedMaxDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).unwrap()
|
|
866
|
+
widthSizingMode = SizingMode.FitContent
|
|
867
|
+
else:
|
|
868
|
+
width = ownerWidth
|
|
869
|
+
widthSizingMode = SizingMode.MaxContent if isnan(width) else SizingMode.StretchFit
|
|
870
|
+
height = float("nan")
|
|
871
|
+
heightSizingMode = SizingMode.MaxContent
|
|
872
|
+
if node.hasDefiniteLength(YGDimension.YGDimensionHeight, ownerHeight):
|
|
873
|
+
height = node.getResolvedDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).unwrap() + node.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionColumn, ownerWidth)
|
|
874
|
+
heightSizingMode = SizingMode.StretchFit
|
|
875
|
+
elif style.resolvedMaxDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).isDefined():
|
|
876
|
+
height = style.resolvedMaxDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).unwrap()
|
|
877
|
+
heightSizingMode = SizingMode.FitContent
|
|
878
|
+
else:
|
|
879
|
+
height = ownerHeight
|
|
880
|
+
heightSizingMode = SizingMode.MaxContent if isnan(height) else SizingMode.StretchFit
|
|
881
|
+
if calculateLayoutInternal(
|
|
882
|
+
node,
|
|
883
|
+
width,
|
|
884
|
+
height,
|
|
885
|
+
ownerDirection,
|
|
886
|
+
widthSizingMode,
|
|
887
|
+
heightSizingMode,
|
|
888
|
+
ownerWidth,
|
|
889
|
+
ownerHeight,
|
|
890
|
+
True,
|
|
891
|
+
LayoutPassReason.kInitial,
|
|
892
|
+
layoutMarkerData,
|
|
893
|
+
0,
|
|
894
|
+
gCurrentGenerationCount,
|
|
895
|
+
):
|
|
896
|
+
node.setPosition(node.getLayout().direction(), ownerWidth, ownerHeight)
|
|
897
|
+
roundLayoutResultsToPixelGrid(node, 0.0, 0.0)
|
|
898
|
+
Event.publish(node, Event.LayoutPassEnd, LayoutPassEndData(layoutMarkerData))
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
def calculateLayoutImpl(
|
|
902
|
+
node: Node,
|
|
903
|
+
availableWidth: float,
|
|
904
|
+
availableHeight: float,
|
|
905
|
+
ownerDirection: YGDirection,
|
|
906
|
+
widthSizingMode: SizingMode,
|
|
907
|
+
heightSizingMode: SizingMode,
|
|
908
|
+
ownerWidth: float,
|
|
909
|
+
ownerHeight: float,
|
|
910
|
+
performLayout: bool,
|
|
911
|
+
reason: LayoutPassReason,
|
|
912
|
+
layoutMarkerData: LayoutData,
|
|
913
|
+
depth: int,
|
|
914
|
+
generationCount: int,
|
|
915
|
+
) -> None:
|
|
916
|
+
if isnan(availableWidth):
|
|
917
|
+
assert widthSizingMode == SizingMode.MaxContent
|
|
918
|
+
if isnan(availableHeight):
|
|
919
|
+
assert heightSizingMode == SizingMode.MaxContent
|
|
920
|
+
if performLayout:
|
|
921
|
+
layoutMarkerData.layouts += 1
|
|
922
|
+
else:
|
|
923
|
+
layoutMarkerData.measures += 1
|
|
924
|
+
direction = node.resolveDirection(ownerDirection)
|
|
925
|
+
node.setLayoutDirection(direction)
|
|
926
|
+
flexRowDirection = resolveDirection(YGFlexDirection.YGFlexDirectionRow, direction)
|
|
927
|
+
flexColumnDirection = resolveDirection(YGFlexDirection.YGFlexDirectionColumn, direction)
|
|
928
|
+
startEdge = YGEdge.YGEdgeLeft if direction == YGDirection.YGDirectionLTR else YGEdge.YGEdgeRight
|
|
929
|
+
endEdge = YGEdge.YGEdgeRight if direction == YGDirection.YGDirectionLTR else YGEdge.YGEdgeLeft
|
|
930
|
+
marginRowLeading = node.style().computeInlineStartMargin(flexRowDirection, direction, ownerWidth)
|
|
931
|
+
node.setLayoutMargin(marginRowLeading, startEdge)
|
|
932
|
+
marginRowTrailing = node.style().computeInlineEndMargin(flexRowDirection, direction, ownerWidth)
|
|
933
|
+
node.setLayoutMargin(marginRowTrailing, endEdge)
|
|
934
|
+
marginColumnLeading = node.style().computeInlineStartMargin(flexColumnDirection, direction, ownerWidth)
|
|
935
|
+
node.setLayoutMargin(marginColumnLeading, YGEdge.YGEdgeTop)
|
|
936
|
+
marginColumnTrailing = node.style().computeInlineEndMargin(flexColumnDirection, direction, ownerWidth)
|
|
937
|
+
node.setLayoutMargin(marginColumnTrailing, YGEdge.YGEdgeBottom)
|
|
938
|
+
marginAxisRow = marginRowLeading + marginRowTrailing
|
|
939
|
+
marginAxisColumn = marginColumnLeading + marginColumnTrailing
|
|
940
|
+
node.setLayoutBorder(node.style().computeInlineStartBorder(flexRowDirection, direction), startEdge)
|
|
941
|
+
node.setLayoutBorder(node.style().computeInlineEndBorder(flexRowDirection, direction), endEdge)
|
|
942
|
+
node.setLayoutBorder(node.style().computeInlineStartBorder(flexColumnDirection, direction), YGEdge.YGEdgeTop)
|
|
943
|
+
node.setLayoutBorder(node.style().computeInlineEndBorder(flexColumnDirection, direction), YGEdge.YGEdgeBottom)
|
|
944
|
+
node.setLayoutPadding(node.style().computeInlineStartPadding(flexRowDirection, direction, ownerWidth), startEdge)
|
|
945
|
+
node.setLayoutPadding(node.style().computeInlineEndPadding(flexRowDirection, direction, ownerWidth), endEdge)
|
|
946
|
+
node.setLayoutPadding(node.style().computeInlineStartPadding(flexColumnDirection, direction, ownerWidth), YGEdge.YGEdgeTop)
|
|
947
|
+
node.setLayoutPadding(node.style().computeInlineEndPadding(flexColumnDirection, direction, ownerWidth), YGEdge.YGEdgeBottom)
|
|
948
|
+
if node.hasMeasureFunc():
|
|
949
|
+
measureNodeWithMeasureFunc(
|
|
950
|
+
node,
|
|
951
|
+
direction,
|
|
952
|
+
availableWidth - marginAxisRow,
|
|
953
|
+
availableHeight - marginAxisColumn,
|
|
954
|
+
widthSizingMode,
|
|
955
|
+
heightSizingMode,
|
|
956
|
+
ownerWidth,
|
|
957
|
+
ownerHeight,
|
|
958
|
+
layoutMarkerData,
|
|
959
|
+
reason,
|
|
960
|
+
)
|
|
961
|
+
cleanupContentsNodesRecursively(node)
|
|
962
|
+
return
|
|
963
|
+
childCount = node.getLayoutChildCount()
|
|
964
|
+
if childCount == 0:
|
|
965
|
+
measureNodeWithoutChildren(
|
|
966
|
+
node,
|
|
967
|
+
direction,
|
|
968
|
+
availableWidth - marginAxisRow,
|
|
969
|
+
availableHeight - marginAxisColumn,
|
|
970
|
+
widthSizingMode,
|
|
971
|
+
heightSizingMode,
|
|
972
|
+
ownerWidth,
|
|
973
|
+
ownerHeight,
|
|
974
|
+
)
|
|
975
|
+
cleanupContentsNodesRecursively(node)
|
|
976
|
+
return
|
|
977
|
+
if not performLayout and measureNodeWithFixedSize(
|
|
978
|
+
node,
|
|
979
|
+
direction,
|
|
980
|
+
availableWidth - marginAxisRow,
|
|
981
|
+
availableHeight - marginAxisColumn,
|
|
982
|
+
widthSizingMode,
|
|
983
|
+
heightSizingMode,
|
|
984
|
+
ownerWidth,
|
|
985
|
+
ownerHeight,
|
|
986
|
+
):
|
|
987
|
+
cleanupContentsNodesRecursively(node)
|
|
988
|
+
return
|
|
989
|
+
node.cloneChildrenIfNeeded()
|
|
990
|
+
node.setLayoutHadOverflow(False)
|
|
991
|
+
cleanupContentsNodesRecursively(node)
|
|
992
|
+
mainAxis = resolveDirection(node.style().flexDirection(), direction)
|
|
993
|
+
crossAxis = resolveCrossDirection(mainAxis, direction)
|
|
994
|
+
isMainAxisRow = isRow(mainAxis)
|
|
995
|
+
isNodeFlexWrap = node.style().flexWrap() != YGWrap.YGWrapNoWrap
|
|
996
|
+
mainAxisOwnerSize = ownerWidth if isMainAxisRow else ownerHeight
|
|
997
|
+
crossAxisOwnerSize = ownerHeight if isMainAxisRow else ownerWidth
|
|
998
|
+
paddingAndBorderAxisMain = paddingAndBorderForAxis(node, mainAxis, direction, ownerWidth)
|
|
999
|
+
paddingAndBorderAxisCross = paddingAndBorderForAxis(node, crossAxis, direction, ownerWidth)
|
|
1000
|
+
leadingPaddingAndBorderCross = node.style().computeFlexStartPaddingAndBorder(crossAxis, direction, ownerWidth)
|
|
1001
|
+
sizingModeMainDim = widthSizingMode if isMainAxisRow else heightSizingMode
|
|
1002
|
+
sizingModeCrossDim = heightSizingMode if isMainAxisRow else widthSizingMode
|
|
1003
|
+
paddingAndBorderAxisRow = paddingAndBorderAxisMain if isMainAxisRow else paddingAndBorderAxisCross
|
|
1004
|
+
paddingAndBorderAxisColumn = paddingAndBorderAxisCross if isMainAxisRow else paddingAndBorderAxisMain
|
|
1005
|
+
availableInnerWidth = calculateAvailableInnerDimension(
|
|
1006
|
+
node,
|
|
1007
|
+
direction,
|
|
1008
|
+
YGDimension.YGDimensionWidth,
|
|
1009
|
+
availableWidth - marginAxisRow,
|
|
1010
|
+
paddingAndBorderAxisRow,
|
|
1011
|
+
ownerWidth,
|
|
1012
|
+
ownerWidth,
|
|
1013
|
+
)
|
|
1014
|
+
availableInnerHeight = calculateAvailableInnerDimension(
|
|
1015
|
+
node,
|
|
1016
|
+
direction,
|
|
1017
|
+
YGDimension.YGDimensionHeight,
|
|
1018
|
+
availableHeight - marginAxisColumn,
|
|
1019
|
+
paddingAndBorderAxisColumn,
|
|
1020
|
+
ownerHeight,
|
|
1021
|
+
ownerWidth,
|
|
1022
|
+
)
|
|
1023
|
+
availableInnerMainDim = availableInnerWidth if isMainAxisRow else availableInnerHeight
|
|
1024
|
+
availableInnerCrossDim = availableInnerHeight if isMainAxisRow else availableInnerWidth
|
|
1025
|
+
totalMainDim = computeFlexBasisForChildren(
|
|
1026
|
+
node,
|
|
1027
|
+
availableInnerWidth,
|
|
1028
|
+
availableInnerHeight,
|
|
1029
|
+
widthSizingMode,
|
|
1030
|
+
heightSizingMode,
|
|
1031
|
+
direction,
|
|
1032
|
+
mainAxis,
|
|
1033
|
+
performLayout,
|
|
1034
|
+
layoutMarkerData,
|
|
1035
|
+
depth,
|
|
1036
|
+
generationCount,
|
|
1037
|
+
)
|
|
1038
|
+
if childCount > 1:
|
|
1039
|
+
totalMainDim = float32(
|
|
1040
|
+
totalMainDim
|
|
1041
|
+
+ float32(
|
|
1042
|
+
node.style().computeGapForAxis(mainAxis, availableInnerMainDim)
|
|
1043
|
+
* float(childCount - 1)
|
|
1044
|
+
)
|
|
1045
|
+
)
|
|
1046
|
+
mainAxisOverflows = sizingModeMainDim != SizingMode.MaxContent and availableInnerMainDim == availableInnerMainDim and totalMainDim > availableInnerMainDim
|
|
1047
|
+
if isNodeFlexWrap and mainAxisOverflows and sizingModeMainDim == SizingMode.FitContent:
|
|
1048
|
+
sizingModeMainDim = SizingMode.StretchFit
|
|
1049
|
+
layoutChildren = list(node.getLayoutChildren())
|
|
1050
|
+
lineCount = 0
|
|
1051
|
+
totalLineCrossDim = 0.0
|
|
1052
|
+
crossAxisGap = node.style().computeGapForAxis(crossAxis, availableInnerCrossDim)
|
|
1053
|
+
maxLineMainDim = 0.0
|
|
1054
|
+
startIndex = 0
|
|
1055
|
+
while startIndex < len(layoutChildren):
|
|
1056
|
+
flexLine = calculateFlexLine(
|
|
1057
|
+
node,
|
|
1058
|
+
ownerDirection,
|
|
1059
|
+
ownerWidth,
|
|
1060
|
+
mainAxisOwnerSize,
|
|
1061
|
+
availableInnerWidth,
|
|
1062
|
+
availableInnerMainDim,
|
|
1063
|
+
layoutChildren,
|
|
1064
|
+
startIndex,
|
|
1065
|
+
lineCount,
|
|
1066
|
+
)
|
|
1067
|
+
canSkipFlex = (not performLayout) and sizingModeCrossDim == SizingMode.StretchFit
|
|
1068
|
+
sizeBasedOnContent = False
|
|
1069
|
+
if sizingModeMainDim != SizingMode.StretchFit:
|
|
1070
|
+
style = node.style()
|
|
1071
|
+
minInnerWidth = style.resolvedMinDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).unwrap() - paddingAndBorderAxisRow
|
|
1072
|
+
maxInnerWidth = style.resolvedMaxDimension(direction, YGDimension.YGDimensionWidth, ownerWidth, ownerWidth).unwrap() - paddingAndBorderAxisRow
|
|
1073
|
+
minInnerHeight = style.resolvedMinDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).unwrap() - paddingAndBorderAxisColumn
|
|
1074
|
+
maxInnerHeight = style.resolvedMaxDimension(direction, YGDimension.YGDimensionHeight, ownerHeight, ownerWidth).unwrap() - paddingAndBorderAxisColumn
|
|
1075
|
+
minInnerMainDim = minInnerWidth if isMainAxisRow else minInnerHeight
|
|
1076
|
+
maxInnerMainDim = maxInnerWidth if isMainAxisRow else maxInnerHeight
|
|
1077
|
+
if minInnerMainDim == minInnerMainDim and flexLine.sizeConsumed < minInnerMainDim:
|
|
1078
|
+
availableInnerMainDim = minInnerMainDim
|
|
1079
|
+
elif maxInnerMainDim == maxInnerMainDim and flexLine.sizeConsumed > maxInnerMainDim:
|
|
1080
|
+
availableInnerMainDim = maxInnerMainDim
|
|
1081
|
+
else:
|
|
1082
|
+
useLegacyStretchBehaviour = node.hasErrata(YGErrata.YGErrataStretchFlexBasis)
|
|
1083
|
+
if (not useLegacyStretchBehaviour) and (
|
|
1084
|
+
(flexLine.layout.totalFlexGrowFactors == flexLine.layout.totalFlexGrowFactors and flexLine.layout.totalFlexGrowFactors == 0)
|
|
1085
|
+
or (node.resolveFlexGrow() == node.resolveFlexGrow() and node.resolveFlexGrow() == 0)
|
|
1086
|
+
):
|
|
1087
|
+
availableInnerMainDim = flexLine.sizeConsumed
|
|
1088
|
+
sizeBasedOnContent = not useLegacyStretchBehaviour
|
|
1089
|
+
if (not sizeBasedOnContent) and availableInnerMainDim == availableInnerMainDim:
|
|
1090
|
+
flexLine.layout.remainingFreeSpace = float32(
|
|
1091
|
+
availableInnerMainDim - flexLine.sizeConsumed
|
|
1092
|
+
)
|
|
1093
|
+
elif flexLine.sizeConsumed < 0:
|
|
1094
|
+
flexLine.layout.remainingFreeSpace = float32(-flexLine.sizeConsumed)
|
|
1095
|
+
if not canSkipFlex:
|
|
1096
|
+
resolveFlexibleLength(
|
|
1097
|
+
node,
|
|
1098
|
+
flexLine,
|
|
1099
|
+
mainAxis,
|
|
1100
|
+
crossAxis,
|
|
1101
|
+
direction,
|
|
1102
|
+
ownerWidth,
|
|
1103
|
+
mainAxisOwnerSize,
|
|
1104
|
+
availableInnerMainDim,
|
|
1105
|
+
availableInnerCrossDim,
|
|
1106
|
+
availableInnerWidth,
|
|
1107
|
+
availableInnerHeight,
|
|
1108
|
+
mainAxisOverflows,
|
|
1109
|
+
sizingModeCrossDim,
|
|
1110
|
+
performLayout,
|
|
1111
|
+
layoutMarkerData,
|
|
1112
|
+
depth,
|
|
1113
|
+
generationCount,
|
|
1114
|
+
)
|
|
1115
|
+
node.setLayoutHadOverflow(
|
|
1116
|
+
node.getLayout().hadOverflow() or (flexLine.layout.remainingFreeSpace < 0)
|
|
1117
|
+
)
|
|
1118
|
+
justifyMainAxis(
|
|
1119
|
+
node,
|
|
1120
|
+
flexLine,
|
|
1121
|
+
mainAxis,
|
|
1122
|
+
crossAxis,
|
|
1123
|
+
direction,
|
|
1124
|
+
sizingModeMainDim,
|
|
1125
|
+
sizingModeCrossDim,
|
|
1126
|
+
mainAxisOwnerSize,
|
|
1127
|
+
ownerWidth,
|
|
1128
|
+
availableInnerMainDim,
|
|
1129
|
+
availableInnerCrossDim,
|
|
1130
|
+
availableInnerWidth,
|
|
1131
|
+
performLayout,
|
|
1132
|
+
)
|
|
1133
|
+
containerCrossAxis = availableInnerCrossDim
|
|
1134
|
+
if sizingModeCrossDim in (SizingMode.MaxContent, SizingMode.FitContent):
|
|
1135
|
+
containerCrossAxis = (
|
|
1136
|
+
boundAxis(
|
|
1137
|
+
node,
|
|
1138
|
+
crossAxis,
|
|
1139
|
+
direction,
|
|
1140
|
+
flexLine.layout.crossDim + paddingAndBorderAxisCross,
|
|
1141
|
+
crossAxisOwnerSize,
|
|
1142
|
+
ownerWidth,
|
|
1143
|
+
)
|
|
1144
|
+
- paddingAndBorderAxisCross
|
|
1145
|
+
)
|
|
1146
|
+
if (not isNodeFlexWrap) and sizingModeCrossDim == SizingMode.StretchFit:
|
|
1147
|
+
flexLine.layout.crossDim = availableInnerCrossDim
|
|
1148
|
+
if not isNodeFlexWrap:
|
|
1149
|
+
flexLine.layout.crossDim = (
|
|
1150
|
+
boundAxis(
|
|
1151
|
+
node,
|
|
1152
|
+
crossAxis,
|
|
1153
|
+
direction,
|
|
1154
|
+
flexLine.layout.crossDim + paddingAndBorderAxisCross,
|
|
1155
|
+
crossAxisOwnerSize,
|
|
1156
|
+
ownerWidth,
|
|
1157
|
+
)
|
|
1158
|
+
- paddingAndBorderAxisCross
|
|
1159
|
+
)
|
|
1160
|
+
if performLayout:
|
|
1161
|
+
for child in flexLine.itemsInFlow:
|
|
1162
|
+
leadingCrossDim = leadingPaddingAndBorderCross
|
|
1163
|
+
alignItem = resolveChildAlignment(node, child)
|
|
1164
|
+
if (
|
|
1165
|
+
alignItem == YGAlign.YGAlignStretch
|
|
1166
|
+
and not child.style().flexStartMarginIsAuto(crossAxis, direction)
|
|
1167
|
+
and not child.style().flexEndMarginIsAuto(crossAxis, direction)
|
|
1168
|
+
):
|
|
1169
|
+
if not child.hasDefiniteLength(dimension(crossAxis), availableInnerCrossDim):
|
|
1170
|
+
childMainSize = child.getLayout().measuredDimension(dimension(mainAxis))
|
|
1171
|
+
childStyle = child.style()
|
|
1172
|
+
if childStyle.aspectRatio().isDefined():
|
|
1173
|
+
childCrossSize = child.style().computeMarginForAxis(crossAxis, availableInnerWidth) + (
|
|
1174
|
+
childMainSize / childStyle.aspectRatio().unwrap()
|
|
1175
|
+
if isMainAxisRow
|
|
1176
|
+
else childMainSize * childStyle.aspectRatio().unwrap()
|
|
1177
|
+
)
|
|
1178
|
+
else:
|
|
1179
|
+
childCrossSize = flexLine.layout.crossDim
|
|
1180
|
+
childMainSize += child.style().computeMarginForAxis(mainAxis, availableInnerWidth)
|
|
1181
|
+
childMainSizingMode = SizingMode.StretchFit
|
|
1182
|
+
childCrossSizingMode = SizingMode.StretchFit
|
|
1183
|
+
childMainSizingMode, childMainSize = constrainMaxSizeForMode(
|
|
1184
|
+
child, direction, mainAxis, availableInnerMainDim, availableInnerWidth, childMainSizingMode, childMainSize
|
|
1185
|
+
)
|
|
1186
|
+
childCrossSizingMode, childCrossSize = constrainMaxSizeForMode(
|
|
1187
|
+
child, direction, crossAxis, availableInnerCrossDim, availableInnerWidth, childCrossSizingMode, childCrossSize
|
|
1188
|
+
)
|
|
1189
|
+
childWidth = childMainSize if isMainAxisRow else childCrossSize
|
|
1190
|
+
childHeight = childMainSize if not isMainAxisRow else childCrossSize
|
|
1191
|
+
alignContent = node.style().alignContent()
|
|
1192
|
+
crossAxisDoesNotGrow = alignContent != YGAlign.YGAlignStretch and isNodeFlexWrap
|
|
1193
|
+
childWidthSizingMode = (
|
|
1194
|
+
SizingMode.MaxContent if isnan(childWidth) or ((not isMainAxisRow) and crossAxisDoesNotGrow) else SizingMode.StretchFit
|
|
1195
|
+
)
|
|
1196
|
+
childHeightSizingMode = (
|
|
1197
|
+
SizingMode.MaxContent if isnan(childHeight) or (isMainAxisRow and crossAxisDoesNotGrow) else SizingMode.StretchFit
|
|
1198
|
+
)
|
|
1199
|
+
calculateLayoutInternal(
|
|
1200
|
+
child,
|
|
1201
|
+
childWidth,
|
|
1202
|
+
childHeight,
|
|
1203
|
+
direction,
|
|
1204
|
+
childWidthSizingMode,
|
|
1205
|
+
childHeightSizingMode,
|
|
1206
|
+
availableInnerWidth,
|
|
1207
|
+
availableInnerHeight,
|
|
1208
|
+
True,
|
|
1209
|
+
LayoutPassReason.kStretch,
|
|
1210
|
+
layoutMarkerData,
|
|
1211
|
+
depth,
|
|
1212
|
+
generationCount,
|
|
1213
|
+
)
|
|
1214
|
+
else:
|
|
1215
|
+
remainingCrossDim = containerCrossAxis - child.dimensionWithMargin(crossAxis, availableInnerWidth)
|
|
1216
|
+
if child.style().flexStartMarginIsAuto(crossAxis, direction) and child.style().flexEndMarginIsAuto(crossAxis, direction):
|
|
1217
|
+
leadingCrossDim += maxOrDefined(0.0, remainingCrossDim / 2)
|
|
1218
|
+
elif child.style().flexEndMarginIsAuto(crossAxis, direction):
|
|
1219
|
+
pass
|
|
1220
|
+
elif child.style().flexStartMarginIsAuto(crossAxis, direction):
|
|
1221
|
+
leadingCrossDim += maxOrDefined(0.0, remainingCrossDim)
|
|
1222
|
+
elif alignItem == YGAlign.YGAlignCenter:
|
|
1223
|
+
leadingCrossDim += remainingCrossDim / 2
|
|
1224
|
+
elif alignItem not in (YGAlign.YGAlignFlexStart,):
|
|
1225
|
+
leadingCrossDim += remainingCrossDim
|
|
1226
|
+
child.setLayoutPosition(
|
|
1227
|
+
child.getLayout().position(flexStartEdge(crossAxis)) + totalLineCrossDim + leadingCrossDim,
|
|
1228
|
+
flexStartEdge(crossAxis),
|
|
1229
|
+
)
|
|
1230
|
+
appliedCrossGap = crossAxisGap if lineCount != 0 else 0.0
|
|
1231
|
+
totalLineCrossDim += flexLine.layout.crossDim + appliedCrossGap
|
|
1232
|
+
maxLineMainDim = maxOrDefined(maxLineMainDim, flexLine.layout.mainDim)
|
|
1233
|
+
nextStartIndex = startIndex
|
|
1234
|
+
lineChildIndex = 0
|
|
1235
|
+
while nextStartIndex < len(layoutChildren):
|
|
1236
|
+
child = layoutChildren[nextStartIndex]
|
|
1237
|
+
if child.style().display() == YGDisplay.YGDisplayNone or child.style().positionType() == YGPositionType.YGPositionTypeAbsolute:
|
|
1238
|
+
nextStartIndex += 1
|
|
1239
|
+
continue
|
|
1240
|
+
|
|
1241
|
+
if lineChildIndex < len(flexLine.itemsInFlow) and child == flexLine.itemsInFlow[lineChildIndex]:
|
|
1242
|
+
lineChildIndex += 1
|
|
1243
|
+
nextStartIndex += 1
|
|
1244
|
+
if lineChildIndex == len(flexLine.itemsInFlow):
|
|
1245
|
+
break
|
|
1246
|
+
continue
|
|
1247
|
+
|
|
1248
|
+
break
|
|
1249
|
+
|
|
1250
|
+
while nextStartIndex < len(layoutChildren):
|
|
1251
|
+
child = layoutChildren[nextStartIndex]
|
|
1252
|
+
if child.style().display() == YGDisplay.YGDisplayNone or child.style().positionType() == YGPositionType.YGPositionTypeAbsolute:
|
|
1253
|
+
nextStartIndex += 1
|
|
1254
|
+
continue
|
|
1255
|
+
break
|
|
1256
|
+
|
|
1257
|
+
startIndex = nextStartIndex
|
|
1258
|
+
lineCount += 1
|
|
1259
|
+
if performLayout and (isNodeFlexWrap or isBaselineLayout(node)):
|
|
1260
|
+
leadPerLine = 0.0
|
|
1261
|
+
currentLead = leadingPaddingAndBorderCross
|
|
1262
|
+
extraSpacePerLine = 0.0
|
|
1263
|
+
if sizingModeCrossDim == SizingMode.StretchFit:
|
|
1264
|
+
unclampedCrossDim = availableInnerCrossDim + paddingAndBorderAxisCross
|
|
1265
|
+
elif node.hasDefiniteLength(dimension(crossAxis), crossAxisOwnerSize):
|
|
1266
|
+
unclampedCrossDim = node.getResolvedDimension(
|
|
1267
|
+
direction,
|
|
1268
|
+
dimension(crossAxis),
|
|
1269
|
+
crossAxisOwnerSize,
|
|
1270
|
+
ownerWidth,
|
|
1271
|
+
).unwrap()
|
|
1272
|
+
else:
|
|
1273
|
+
unclampedCrossDim = totalLineCrossDim + paddingAndBorderAxisCross
|
|
1274
|
+
innerCrossDim = (
|
|
1275
|
+
boundAxis(
|
|
1276
|
+
node,
|
|
1277
|
+
crossAxis,
|
|
1278
|
+
direction,
|
|
1279
|
+
unclampedCrossDim,
|
|
1280
|
+
crossAxisOwnerSize,
|
|
1281
|
+
ownerWidth,
|
|
1282
|
+
)
|
|
1283
|
+
- paddingAndBorderAxisCross
|
|
1284
|
+
)
|
|
1285
|
+
remainingAlignContentDim = innerCrossDim - totalLineCrossDim
|
|
1286
|
+
alignContent = (
|
|
1287
|
+
node.style().alignContent()
|
|
1288
|
+
if remainingAlignContentDim >= 0
|
|
1289
|
+
else fallbackAlignment(node.style().alignContent())
|
|
1290
|
+
)
|
|
1291
|
+
if alignContent == YGAlign.YGAlignFlexEnd:
|
|
1292
|
+
currentLead += remainingAlignContentDim
|
|
1293
|
+
elif alignContent == YGAlign.YGAlignCenter:
|
|
1294
|
+
currentLead += remainingAlignContentDim / 2
|
|
1295
|
+
elif alignContent == YGAlign.YGAlignStretch:
|
|
1296
|
+
extraSpacePerLine = floatDivision(
|
|
1297
|
+
remainingAlignContentDim, float(lineCount)
|
|
1298
|
+
)
|
|
1299
|
+
elif alignContent == YGAlign.YGAlignSpaceAround:
|
|
1300
|
+
currentLead += floatDivision(
|
|
1301
|
+
remainingAlignContentDim, 2 * float(lineCount)
|
|
1302
|
+
)
|
|
1303
|
+
leadPerLine = floatDivision(
|
|
1304
|
+
remainingAlignContentDim, float(lineCount)
|
|
1305
|
+
)
|
|
1306
|
+
elif alignContent == YGAlign.YGAlignSpaceEvenly:
|
|
1307
|
+
currentLead += remainingAlignContentDim / float(lineCount + 1)
|
|
1308
|
+
leadPerLine = remainingAlignContentDim / float(lineCount + 1)
|
|
1309
|
+
elif alignContent == YGAlign.YGAlignSpaceBetween and lineCount > 1:
|
|
1310
|
+
leadPerLine = remainingAlignContentDim / float(lineCount - 1)
|
|
1311
|
+
endIndex = 0
|
|
1312
|
+
for i in range(lineCount):
|
|
1313
|
+
startLineIndex = endIndex
|
|
1314
|
+
lineHeight = 0.0
|
|
1315
|
+
maxAscentForCurrentLine = 0.0
|
|
1316
|
+
maxDescentForCurrentLine = 0.0
|
|
1317
|
+
while endIndex < len(layoutChildren):
|
|
1318
|
+
child = layoutChildren[endIndex]
|
|
1319
|
+
endIndex += 1
|
|
1320
|
+
if child.style().display() == YGDisplay.YGDisplayNone:
|
|
1321
|
+
continue
|
|
1322
|
+
if child.style().positionType() != YGPositionType.YGPositionTypeAbsolute:
|
|
1323
|
+
if child.getLineIndex() != i:
|
|
1324
|
+
endIndex -= 1
|
|
1325
|
+
break
|
|
1326
|
+
if child.isLayoutDimensionDefined(crossAxis):
|
|
1327
|
+
lineHeight = maxOrDefined(
|
|
1328
|
+
lineHeight,
|
|
1329
|
+
child.getLayout().measuredDimension(dimension(crossAxis))
|
|
1330
|
+
+ child.style().computeMarginForAxis(crossAxis, availableInnerWidth),
|
|
1331
|
+
)
|
|
1332
|
+
if resolveChildAlignment(node, child) == YGAlign.YGAlignBaseline:
|
|
1333
|
+
ascent = calculateBaseline(child) + child.style().computeFlexStartMargin(
|
|
1334
|
+
YGFlexDirection.YGFlexDirectionColumn, direction, availableInnerWidth
|
|
1335
|
+
)
|
|
1336
|
+
descent = (
|
|
1337
|
+
child.getLayout().measuredDimension(YGDimension.YGDimensionHeight)
|
|
1338
|
+
+ child.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionColumn, availableInnerWidth)
|
|
1339
|
+
- ascent
|
|
1340
|
+
)
|
|
1341
|
+
maxAscentForCurrentLine = maxOrDefined(maxAscentForCurrentLine, ascent)
|
|
1342
|
+
maxDescentForCurrentLine = maxOrDefined(maxDescentForCurrentLine, descent)
|
|
1343
|
+
lineHeight = maxOrDefined(lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine)
|
|
1344
|
+
currentLead += crossAxisGap if i != 0 else 0.0
|
|
1345
|
+
lineHeight += extraSpacePerLine
|
|
1346
|
+
for child in layoutChildren[startLineIndex:endIndex]:
|
|
1347
|
+
if child.style().display() == YGDisplay.YGDisplayNone:
|
|
1348
|
+
continue
|
|
1349
|
+
if child.style().positionType() != YGPositionType.YGPositionTypeAbsolute:
|
|
1350
|
+
childAlignment = resolveChildAlignment(node, child)
|
|
1351
|
+
if childAlignment == YGAlign.YGAlignFlexStart:
|
|
1352
|
+
child.setLayoutPosition(
|
|
1353
|
+
currentLead + child.style().computeFlexStartPosition(crossAxis, direction, availableInnerWidth),
|
|
1354
|
+
flexStartEdge(crossAxis),
|
|
1355
|
+
)
|
|
1356
|
+
elif childAlignment == YGAlign.YGAlignFlexEnd:
|
|
1357
|
+
child.setLayoutPosition(
|
|
1358
|
+
currentLead
|
|
1359
|
+
+ lineHeight
|
|
1360
|
+
- child.style().computeFlexEndMargin(crossAxis, direction, availableInnerWidth)
|
|
1361
|
+
- child.getLayout().measuredDimension(dimension(crossAxis)),
|
|
1362
|
+
flexStartEdge(crossAxis),
|
|
1363
|
+
)
|
|
1364
|
+
elif childAlignment == YGAlign.YGAlignCenter:
|
|
1365
|
+
childHeight = child.getLayout().measuredDimension(dimension(crossAxis))
|
|
1366
|
+
child.setLayoutPosition(
|
|
1367
|
+
currentLead + (lineHeight - childHeight) / 2,
|
|
1368
|
+
flexStartEdge(crossAxis),
|
|
1369
|
+
)
|
|
1370
|
+
elif childAlignment == YGAlign.YGAlignStretch:
|
|
1371
|
+
child.setLayoutPosition(
|
|
1372
|
+
currentLead + child.style().computeFlexStartMargin(crossAxis, direction, availableInnerWidth),
|
|
1373
|
+
flexStartEdge(crossAxis),
|
|
1374
|
+
)
|
|
1375
|
+
if not child.hasDefiniteLength(dimension(crossAxis), availableInnerCrossDim):
|
|
1376
|
+
childWidth = (
|
|
1377
|
+
child.getLayout().measuredDimension(YGDimension.YGDimensionWidth)
|
|
1378
|
+
+ child.style().computeMarginForAxis(mainAxis, availableInnerWidth)
|
|
1379
|
+
if isMainAxisRow
|
|
1380
|
+
else leadPerLine + lineHeight
|
|
1381
|
+
)
|
|
1382
|
+
childHeight = (
|
|
1383
|
+
child.getLayout().measuredDimension(YGDimension.YGDimensionHeight)
|
|
1384
|
+
+ child.style().computeMarginForAxis(crossAxis, availableInnerWidth)
|
|
1385
|
+
if not isMainAxisRow
|
|
1386
|
+
else leadPerLine + lineHeight
|
|
1387
|
+
)
|
|
1388
|
+
if not (
|
|
1389
|
+
inexactEquals(
|
|
1390
|
+
childWidth,
|
|
1391
|
+
child.getLayout().measuredDimension(YGDimension.YGDimensionWidth),
|
|
1392
|
+
)
|
|
1393
|
+
and inexactEquals(
|
|
1394
|
+
childHeight,
|
|
1395
|
+
child.getLayout().measuredDimension(YGDimension.YGDimensionHeight),
|
|
1396
|
+
)
|
|
1397
|
+
):
|
|
1398
|
+
calculateLayoutInternal(
|
|
1399
|
+
child,
|
|
1400
|
+
childWidth,
|
|
1401
|
+
childHeight,
|
|
1402
|
+
direction,
|
|
1403
|
+
SizingMode.StretchFit,
|
|
1404
|
+
SizingMode.StretchFit,
|
|
1405
|
+
availableInnerWidth,
|
|
1406
|
+
availableInnerHeight,
|
|
1407
|
+
True,
|
|
1408
|
+
LayoutPassReason.kMultilineStretch,
|
|
1409
|
+
layoutMarkerData,
|
|
1410
|
+
depth,
|
|
1411
|
+
generationCount,
|
|
1412
|
+
)
|
|
1413
|
+
elif childAlignment == YGAlign.YGAlignBaseline:
|
|
1414
|
+
child.setLayoutPosition(
|
|
1415
|
+
currentLead
|
|
1416
|
+
+ maxAscentForCurrentLine
|
|
1417
|
+
- calculateBaseline(child)
|
|
1418
|
+
+ child.style().computeFlexStartPosition(
|
|
1419
|
+
YGFlexDirection.YGFlexDirectionColumn,
|
|
1420
|
+
direction,
|
|
1421
|
+
availableInnerCrossDim,
|
|
1422
|
+
),
|
|
1423
|
+
YGEdge.YGEdgeTop,
|
|
1424
|
+
)
|
|
1425
|
+
currentLead = currentLead + leadPerLine + lineHeight
|
|
1426
|
+
node.setLayoutMeasuredDimension(
|
|
1427
|
+
boundAxis(node, YGFlexDirection.YGFlexDirectionRow, direction, availableWidth - marginAxisRow, ownerWidth, ownerWidth),
|
|
1428
|
+
YGDimension.YGDimensionWidth,
|
|
1429
|
+
)
|
|
1430
|
+
node.setLayoutMeasuredDimension(
|
|
1431
|
+
boundAxis(node, YGFlexDirection.YGFlexDirectionColumn, direction, availableHeight - marginAxisColumn, ownerHeight, ownerWidth),
|
|
1432
|
+
YGDimension.YGDimensionHeight,
|
|
1433
|
+
)
|
|
1434
|
+
if sizingModeMainDim == SizingMode.MaxContent or (
|
|
1435
|
+
node.style().overflow() != YGOverflow.YGOverflowScroll and sizingModeMainDim == SizingMode.FitContent
|
|
1436
|
+
):
|
|
1437
|
+
node.setLayoutMeasuredDimension(
|
|
1438
|
+
boundAxis(node, mainAxis, direction, maxLineMainDim, mainAxisOwnerSize, ownerWidth),
|
|
1439
|
+
dimension(mainAxis),
|
|
1440
|
+
)
|
|
1441
|
+
elif sizingModeMainDim == SizingMode.FitContent and node.style().overflow() == YGOverflow.YGOverflowScroll:
|
|
1442
|
+
node.setLayoutMeasuredDimension(
|
|
1443
|
+
maxOrDefined(
|
|
1444
|
+
minOrDefined(
|
|
1445
|
+
availableInnerMainDim + paddingAndBorderAxisMain,
|
|
1446
|
+
boundAxisWithinMinAndMax(
|
|
1447
|
+
node, direction, mainAxis, FloatOptional(maxLineMainDim), mainAxisOwnerSize, ownerWidth
|
|
1448
|
+
).unwrap(),
|
|
1449
|
+
),
|
|
1450
|
+
paddingAndBorderAxisMain,
|
|
1451
|
+
),
|
|
1452
|
+
dimension(mainAxis),
|
|
1453
|
+
)
|
|
1454
|
+
if sizingModeCrossDim == SizingMode.MaxContent or (
|
|
1455
|
+
node.style().overflow() != YGOverflow.YGOverflowScroll and sizingModeCrossDim == SizingMode.FitContent
|
|
1456
|
+
):
|
|
1457
|
+
node.setLayoutMeasuredDimension(
|
|
1458
|
+
boundAxis(node, crossAxis, direction, totalLineCrossDim + paddingAndBorderAxisCross, crossAxisOwnerSize, ownerWidth),
|
|
1459
|
+
dimension(crossAxis),
|
|
1460
|
+
)
|
|
1461
|
+
elif sizingModeCrossDim == SizingMode.FitContent and node.style().overflow() == YGOverflow.YGOverflowScroll:
|
|
1462
|
+
node.setLayoutMeasuredDimension(
|
|
1463
|
+
maxOrDefined(
|
|
1464
|
+
minOrDefined(
|
|
1465
|
+
availableInnerCrossDim + paddingAndBorderAxisCross,
|
|
1466
|
+
boundAxisWithinMinAndMax(
|
|
1467
|
+
node,
|
|
1468
|
+
direction,
|
|
1469
|
+
crossAxis,
|
|
1470
|
+
FloatOptional(totalLineCrossDim + paddingAndBorderAxisCross),
|
|
1471
|
+
crossAxisOwnerSize,
|
|
1472
|
+
ownerWidth,
|
|
1473
|
+
).unwrap(),
|
|
1474
|
+
),
|
|
1475
|
+
paddingAndBorderAxisCross,
|
|
1476
|
+
),
|
|
1477
|
+
dimension(crossAxis),
|
|
1478
|
+
)
|
|
1479
|
+
if performLayout and node.style().flexWrap() == YGWrap.YGWrapWrapReverse:
|
|
1480
|
+
for child in node.getLayoutChildren():
|
|
1481
|
+
if child.style().positionType() != YGPositionType.YGPositionTypeAbsolute:
|
|
1482
|
+
child.setLayoutPosition(
|
|
1483
|
+
node.getLayout().measuredDimension(dimension(crossAxis))
|
|
1484
|
+
- child.getLayout().position(flexStartEdge(crossAxis))
|
|
1485
|
+
- child.getLayout().measuredDimension(dimension(crossAxis)),
|
|
1486
|
+
flexStartEdge(crossAxis),
|
|
1487
|
+
)
|
|
1488
|
+
if performLayout:
|
|
1489
|
+
needsMainTrailingPos = needsTrailingPosition(mainAxis)
|
|
1490
|
+
needsCrossTrailingPos = needsTrailingPosition(crossAxis)
|
|
1491
|
+
if needsMainTrailingPos or needsCrossTrailingPos:
|
|
1492
|
+
for child in node.getLayoutChildren():
|
|
1493
|
+
if child.style().display() == YGDisplay.YGDisplayNone or child.style().positionType() == YGPositionType.YGPositionTypeAbsolute:
|
|
1494
|
+
continue
|
|
1495
|
+
if needsMainTrailingPos:
|
|
1496
|
+
setChildTrailingPosition(node, child, mainAxis)
|
|
1497
|
+
if needsCrossTrailingPos:
|
|
1498
|
+
setChildTrailingPosition(node, child, crossAxis)
|
|
1499
|
+
if node.style().positionType() != YGPositionType.YGPositionTypeStatic or node.alwaysFormsContainingBlock() or depth == 1:
|
|
1500
|
+
layoutAbsoluteDescendants(
|
|
1501
|
+
node,
|
|
1502
|
+
node,
|
|
1503
|
+
sizingModeMainDim if isMainAxisRow else sizingModeCrossDim,
|
|
1504
|
+
direction,
|
|
1505
|
+
layoutMarkerData,
|
|
1506
|
+
depth,
|
|
1507
|
+
generationCount,
|
|
1508
|
+
0.0,
|
|
1509
|
+
0.0,
|
|
1510
|
+
availableInnerWidth,
|
|
1511
|
+
availableInnerHeight,
|
|
1512
|
+
)
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
def calculateLayoutInternal(
|
|
1516
|
+
node: Node,
|
|
1517
|
+
availableWidth: float,
|
|
1518
|
+
availableHeight: float,
|
|
1519
|
+
ownerDirection: YGDirection,
|
|
1520
|
+
widthSizingMode: SizingMode,
|
|
1521
|
+
heightSizingMode: SizingMode,
|
|
1522
|
+
ownerWidth: float,
|
|
1523
|
+
ownerHeight: float,
|
|
1524
|
+
performLayout: bool,
|
|
1525
|
+
reason: LayoutPassReason,
|
|
1526
|
+
layoutMarkerData: LayoutData,
|
|
1527
|
+
depth: int,
|
|
1528
|
+
generationCount: int,
|
|
1529
|
+
) -> bool:
|
|
1530
|
+
layout = node.getLayout()
|
|
1531
|
+
depth += 1
|
|
1532
|
+
needToVisitNode = (
|
|
1533
|
+
(node.isDirty() and layout.generationCount != generationCount)
|
|
1534
|
+
or layout.configVersion != node.getConfig().getVersion()
|
|
1535
|
+
or layout.lastOwnerDirection != ownerDirection
|
|
1536
|
+
)
|
|
1537
|
+
if needToVisitNode:
|
|
1538
|
+
layout.nextCachedMeasurementsIndex = 0
|
|
1539
|
+
layout.cachedLayout.availableWidth = -1
|
|
1540
|
+
layout.cachedLayout.availableHeight = -1
|
|
1541
|
+
layout.cachedLayout.widthSizingMode = SizingMode.MaxContent
|
|
1542
|
+
layout.cachedLayout.heightSizingMode = SizingMode.MaxContent
|
|
1543
|
+
layout.cachedLayout.computedWidth = -1
|
|
1544
|
+
layout.cachedLayout.computedHeight = -1
|
|
1545
|
+
cachedResults = None
|
|
1546
|
+
if node.hasMeasureFunc():
|
|
1547
|
+
marginAxisRow = node.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionRow, ownerWidth)
|
|
1548
|
+
marginAxisColumn = node.style().computeMarginForAxis(YGFlexDirection.YGFlexDirectionColumn, ownerWidth)
|
|
1549
|
+
if canUseCachedMeasurement(
|
|
1550
|
+
widthSizingMode,
|
|
1551
|
+
availableWidth,
|
|
1552
|
+
heightSizingMode,
|
|
1553
|
+
availableHeight,
|
|
1554
|
+
layout.cachedLayout.widthSizingMode,
|
|
1555
|
+
layout.cachedLayout.availableWidth,
|
|
1556
|
+
layout.cachedLayout.heightSizingMode,
|
|
1557
|
+
layout.cachedLayout.availableHeight,
|
|
1558
|
+
layout.cachedLayout.computedWidth,
|
|
1559
|
+
layout.cachedLayout.computedHeight,
|
|
1560
|
+
marginAxisRow,
|
|
1561
|
+
marginAxisColumn,
|
|
1562
|
+
node.getConfig(),
|
|
1563
|
+
):
|
|
1564
|
+
cachedResults = layout.cachedLayout
|
|
1565
|
+
else:
|
|
1566
|
+
for measurement in layout.cachedMeasurements[: layout.nextCachedMeasurementsIndex]:
|
|
1567
|
+
if canUseCachedMeasurement(
|
|
1568
|
+
widthSizingMode,
|
|
1569
|
+
availableWidth,
|
|
1570
|
+
heightSizingMode,
|
|
1571
|
+
availableHeight,
|
|
1572
|
+
measurement.widthSizingMode,
|
|
1573
|
+
measurement.availableWidth,
|
|
1574
|
+
measurement.heightSizingMode,
|
|
1575
|
+
measurement.availableHeight,
|
|
1576
|
+
measurement.computedWidth,
|
|
1577
|
+
measurement.computedHeight,
|
|
1578
|
+
marginAxisRow,
|
|
1579
|
+
marginAxisColumn,
|
|
1580
|
+
node.getConfig(),
|
|
1581
|
+
):
|
|
1582
|
+
cachedResults = measurement
|
|
1583
|
+
break
|
|
1584
|
+
elif performLayout:
|
|
1585
|
+
if (
|
|
1586
|
+
inexactEquals(availableWidth, layout.cachedLayout.availableWidth)
|
|
1587
|
+
and inexactEquals(availableHeight, layout.cachedLayout.availableHeight)
|
|
1588
|
+
and layout.cachedLayout.widthSizingMode == widthSizingMode
|
|
1589
|
+
and layout.cachedLayout.heightSizingMode == heightSizingMode
|
|
1590
|
+
):
|
|
1591
|
+
cachedResults = layout.cachedLayout
|
|
1592
|
+
else:
|
|
1593
|
+
for measurement in layout.cachedMeasurements[: layout.nextCachedMeasurementsIndex]:
|
|
1594
|
+
if (
|
|
1595
|
+
inexactEquals(availableWidth, measurement.availableWidth)
|
|
1596
|
+
and inexactEquals(availableHeight, measurement.availableHeight)
|
|
1597
|
+
and measurement.widthSizingMode == widthSizingMode
|
|
1598
|
+
and measurement.heightSizingMode == heightSizingMode
|
|
1599
|
+
):
|
|
1600
|
+
cachedResults = measurement
|
|
1601
|
+
break
|
|
1602
|
+
if (not needToVisitNode) and cachedResults is not None:
|
|
1603
|
+
layout.setMeasuredDimension(YGDimension.YGDimensionWidth, cachedResults.computedWidth)
|
|
1604
|
+
layout.setMeasuredDimension(YGDimension.YGDimensionHeight, cachedResults.computedHeight)
|
|
1605
|
+
if performLayout:
|
|
1606
|
+
layoutMarkerData.cachedLayouts += 1
|
|
1607
|
+
else:
|
|
1608
|
+
layoutMarkerData.cachedMeasures += 1
|
|
1609
|
+
else:
|
|
1610
|
+
calculateLayoutImpl(
|
|
1611
|
+
node,
|
|
1612
|
+
availableWidth,
|
|
1613
|
+
availableHeight,
|
|
1614
|
+
ownerDirection,
|
|
1615
|
+
widthSizingMode,
|
|
1616
|
+
heightSizingMode,
|
|
1617
|
+
ownerWidth,
|
|
1618
|
+
ownerHeight,
|
|
1619
|
+
performLayout,
|
|
1620
|
+
reason,
|
|
1621
|
+
layoutMarkerData,
|
|
1622
|
+
depth,
|
|
1623
|
+
generationCount,
|
|
1624
|
+
)
|
|
1625
|
+
layout.lastOwnerDirection = ownerDirection
|
|
1626
|
+
layout.configVersion = node.getConfig().getVersion()
|
|
1627
|
+
if cachedResults is None:
|
|
1628
|
+
layoutMarkerData.maxMeasureCache = max(layoutMarkerData.maxMeasureCache, layout.nextCachedMeasurementsIndex + 1)
|
|
1629
|
+
if layout.nextCachedMeasurementsIndex == LayoutResults.MaxCachedMeasurements:
|
|
1630
|
+
layout.nextCachedMeasurementsIndex = 0
|
|
1631
|
+
newCacheEntry = layout.cachedLayout if performLayout else layout.cachedMeasurements[layout.nextCachedMeasurementsIndex]
|
|
1632
|
+
if not performLayout:
|
|
1633
|
+
layout.nextCachedMeasurementsIndex += 1
|
|
1634
|
+
newCacheEntry.availableWidth = availableWidth
|
|
1635
|
+
newCacheEntry.availableHeight = availableHeight
|
|
1636
|
+
newCacheEntry.widthSizingMode = widthSizingMode
|
|
1637
|
+
newCacheEntry.heightSizingMode = heightSizingMode
|
|
1638
|
+
newCacheEntry.computedWidth = layout.measuredDimension(YGDimension.YGDimensionWidth)
|
|
1639
|
+
newCacheEntry.computedHeight = layout.measuredDimension(YGDimension.YGDimensionHeight)
|
|
1640
|
+
if performLayout:
|
|
1641
|
+
node.setLayoutDimension(layout.measuredDimension(YGDimension.YGDimensionWidth), YGDimension.YGDimensionWidth)
|
|
1642
|
+
node.setLayoutDimension(layout.measuredDimension(YGDimension.YGDimensionHeight), YGDimension.YGDimensionHeight)
|
|
1643
|
+
node.setHasNewLayout(True)
|
|
1644
|
+
node.setDirty(False)
|
|
1645
|
+
layout.generationCount = generationCount
|
|
1646
|
+
if performLayout:
|
|
1647
|
+
layoutType = LayoutType.kCachedLayout if ((not needToVisitNode) and cachedResults is layout.cachedLayout) else LayoutType.kLayout
|
|
1648
|
+
else:
|
|
1649
|
+
layoutType = LayoutType.kCachedMeasure if cachedResults is not None else LayoutType.kMeasure
|
|
1650
|
+
Event.publish(node, Event.NodeLayout, NodeLayoutData(layoutType))
|
|
1651
|
+
return needToVisitNode or cachedResults is None
|