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.
Files changed (51) hide show
  1. yoga/YGConfig.py +92 -0
  2. yoga/YGEnums.py +404 -0
  3. yoga/YGMacros.py +9 -0
  4. yoga/YGNode.py +367 -0
  5. yoga/YGNodeLayout.py +81 -0
  6. yoga/YGNodeStyle.py +876 -0
  7. yoga/YGPixelGrid.py +42 -0
  8. yoga/YGValue.py +49 -0
  9. yoga/__init__.py +16 -0
  10. yoga/algorithm/AbsoluteLayout.py +417 -0
  11. yoga/algorithm/Align.py +34 -0
  12. yoga/algorithm/Baseline.py +54 -0
  13. yoga/algorithm/BoundAxis.py +55 -0
  14. yoga/algorithm/Cache.py +93 -0
  15. yoga/algorithm/CalculateLayout.py +1651 -0
  16. yoga/algorithm/FlexDirection.py +76 -0
  17. yoga/algorithm/FlexLine.py +130 -0
  18. yoga/algorithm/PixelGrid.py +56 -0
  19. yoga/algorithm/SizingMode.py +39 -0
  20. yoga/algorithm/TrailingPosition.py +34 -0
  21. yoga/algorithm/__init__.py +18 -0
  22. yoga/config/Config.py +137 -0
  23. yoga/config/__init__.py +9 -0
  24. yoga/debug/AssertFatal.py +24 -0
  25. yoga/debug/Log.py +49 -0
  26. yoga/debug/__init__.py +10 -0
  27. yoga/event/__init__.py +9 -0
  28. yoga/event/event.py +123 -0
  29. yoga/node/CachedMeasurement.py +51 -0
  30. yoga/node/LayoutResults.py +225 -0
  31. yoga/node/LayoutableChildren.py +79 -0
  32. yoga/node/Node.py +566 -0
  33. yoga/node/__init__.py +11 -0
  34. yoga/numeric/Comparison.py +46 -0
  35. yoga/numeric/FloatMath.py +24 -0
  36. yoga/numeric/FloatOptional.py +65 -0
  37. yoga/numeric/__init__.py +10 -0
  38. yoga/style/GridLine.py +44 -0
  39. yoga/style/GridTrack.py +47 -0
  40. yoga/style/SmallValueBuffer.py +133 -0
  41. yoga/style/Style.py +763 -0
  42. yoga/style/StyleLength.py +88 -0
  43. yoga/style/StyleSizeLength.py +117 -0
  44. yoga/style/StyleValueHandle.py +98 -0
  45. yoga/style/StyleValuePool.py +191 -0
  46. yoga/style/__init__.py +16 -0
  47. yoga_layout_python-0.1.0.dist-info/METADATA +158 -0
  48. yoga_layout_python-0.1.0.dist-info/RECORD +51 -0
  49. yoga_layout_python-0.1.0.dist-info/WHEEL +5 -0
  50. yoga_layout_python-0.1.0.dist-info/licenses/LICENSE +21 -0
  51. yoga_layout_python-0.1.0.dist-info/top_level.txt +1 -0
yoga/YGNode.py ADDED
@@ -0,0 +1,367 @@
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 copy import deepcopy
11
+ from dataclasses import dataclass
12
+
13
+ from .YGConfig import YGConfigGetDefault
14
+ from .YGEnums import YGDirection, YGMeasureMode, YGNodeType
15
+ from .algorithm.Cache import canUseCachedMeasurement
16
+ from .algorithm.CalculateLayout import calculateLayout
17
+ from .algorithm.SizingMode import sizingMode
18
+ from .debug.AssertFatal import assertFatal, assertFatalWithNode
19
+ from .event.event import Event, NodeAllocationData, NodeDeallocationData
20
+ from .node.Node import Node
21
+ from .node.LayoutResults import LayoutResults
22
+
23
+
24
+ YGNodeRef = Node
25
+ YGNodeConstRef = Node
26
+
27
+
28
+ @dataclass
29
+ class YGSize:
30
+ width: float
31
+ height: float
32
+
33
+
34
+ def YGNodeNew() -> YGNodeRef:
35
+ return YGNodeNewWithConfig(YGConfigGetDefault())
36
+
37
+
38
+ def YGNodeNewWithConfig(config) -> YGNodeRef:
39
+ assertFatal(config is not None, "Tried to construct YGNode with null config")
40
+ node = Node(config_=config)
41
+ Event.publish(node, Event.NodeAllocation, NodeAllocationData(config))
42
+ return node
43
+
44
+
45
+ def YGNodeClone(oldNodeRef: YGNodeConstRef) -> YGNodeRef:
46
+ oldNode = oldNodeRef
47
+ node = Node(config_=oldNode.getConfig())
48
+ node.hasNewLayout_ = oldNode.hasNewLayout_
49
+ node.isReferenceBaseline_ = oldNode.isReferenceBaseline_
50
+ node.isDirty_ = oldNode.isDirty_
51
+ node.alwaysFormsContainingBlock_ = oldNode.alwaysFormsContainingBlock_
52
+ node.nodeType_ = oldNode.nodeType_
53
+ node.context_ = oldNode.context_
54
+ node.measureFunc_ = oldNode.measureFunc_
55
+ node.baselineFunc_ = oldNode.baselineFunc_
56
+ node.dirtiedFunc_ = oldNode.dirtiedFunc_
57
+ node.style_ = deepcopy(oldNode.style_)
58
+ node.layout_ = deepcopy(oldNode.layout_)
59
+ node.lineIndex_ = oldNode.lineIndex_
60
+ node.setChildren(list(oldNode.children_))
61
+ node.config_ = oldNode.config_
62
+ node.processedDimensions_ = deepcopy(oldNode.processedDimensions_)
63
+ node.owner_ = None
64
+ Event.publish(node, Event.NodeAllocation, NodeAllocationData(node.getConfig()))
65
+ return node
66
+
67
+
68
+ def YGNodeFree(nodeRef: YGNodeRef) -> None:
69
+ node = nodeRef
70
+
71
+ owner = node.getOwner()
72
+ if owner is not None:
73
+ owner.removeChild(node)
74
+ node.setOwner(None)
75
+
76
+ childCount = node.getChildCount()
77
+ for i in range(childCount):
78
+ child = node.getChild(i)
79
+ child.setOwner(None)
80
+
81
+ node.clearChildren()
82
+ Event.publish(node, Event.NodeDeallocation, NodeDeallocationData(YGNodeGetConfig(node)))
83
+
84
+
85
+ def YGNodeFreeRecursive(rootRef: YGNodeRef) -> None:
86
+ root = rootRef
87
+
88
+ skipped = 0
89
+ while root.getChildCount() > skipped:
90
+ child = root.getChild(skipped)
91
+ if child.getOwner() != root:
92
+ # Don't free shared nodes that we don't own.
93
+ skipped += 1
94
+ else:
95
+ YGNodeRemoveChild(root, child)
96
+ YGNodeFreeRecursive(child)
97
+ YGNodeFree(root)
98
+
99
+
100
+ def YGNodeFinalize(node: YGNodeRef) -> None:
101
+ Event.publish(node, Event.NodeDeallocation, NodeDeallocationData(YGNodeGetConfig(node)))
102
+ del node
103
+
104
+
105
+ def YGNodeReset(node: YGNodeRef) -> None:
106
+ node.reset()
107
+
108
+
109
+ def YGNodeCalculateLayout(
110
+ node: YGNodeRef, ownerWidth: float, ownerHeight: float, ownerDirection: YGDirection
111
+ ) -> None:
112
+ calculateLayout(node, ownerWidth, ownerHeight, ownerDirection)
113
+
114
+
115
+ def YGNodeGetHasNewLayout(node: YGNodeConstRef) -> bool:
116
+ return node.getHasNewLayout()
117
+
118
+
119
+ def YGNodeSetHasNewLayout(node: YGNodeRef, hasNewLayout: bool) -> None:
120
+ node.setHasNewLayout(hasNewLayout)
121
+
122
+
123
+ def YGNodeIsDirty(node: YGNodeConstRef) -> bool:
124
+ return node.isDirty()
125
+
126
+
127
+ def YGNodeMarkDirty(nodeRef: YGNodeRef) -> None:
128
+ assertFatalWithNode(
129
+ nodeRef,
130
+ nodeRef.hasMeasureFunc(),
131
+ "Only leaf nodes with custom measure functions should manually mark themselves as dirty",
132
+ )
133
+ nodeRef.markDirtyAndPropagate()
134
+
135
+
136
+ def YGNodeSetDirtiedFunc(node: YGNodeRef, dirtiedFunc) -> None:
137
+ node.setDirtiedFunc(dirtiedFunc)
138
+
139
+
140
+ def YGNodeGetDirtiedFunc(node: YGNodeConstRef):
141
+ return node.getDirtiedFunc()
142
+
143
+
144
+ def YGNodeInsertChild(ownerRef: YGNodeRef, childRef: YGNodeRef, index: int) -> None:
145
+ owner = ownerRef
146
+ child = childRef
147
+
148
+ assertFatalWithNode(
149
+ owner,
150
+ child.getOwner() is None,
151
+ "Child already has an owner, it must be removed first.",
152
+ )
153
+ assertFatalWithNode(
154
+ owner,
155
+ not owner.hasMeasureFunc(),
156
+ "Cannot add child: Nodes with measure functions cannot have children.",
157
+ )
158
+ owner.insertChild(child, index)
159
+ child.setOwner(owner)
160
+ owner.markDirtyAndPropagate()
161
+
162
+
163
+ def YGNodeSwapChild(ownerRef: YGNodeRef, childRef: YGNodeRef, index: int) -> None:
164
+ owner = ownerRef
165
+ child = childRef
166
+
167
+ owner.replaceChild(child, index)
168
+ child.setOwner(owner)
169
+
170
+
171
+ def YGNodeRemoveChild(ownerRef: YGNodeRef, excludedChildRef: YGNodeRef) -> None:
172
+ owner = ownerRef
173
+ excludedChild = excludedChildRef
174
+
175
+ if owner.getChildCount() == 0:
176
+ # This is an empty set. Nothing to remove.
177
+ return
178
+
179
+ # Children may be shared between parents, which is indicated by not having an
180
+ # owner. We only want to reset the child completely if it is owned
181
+ # exclusively by one node.
182
+ childOwner = excludedChild.getOwner()
183
+ if owner.removeChild(excludedChild):
184
+ if owner == childOwner:
185
+ excludedChild.setLayout(LayoutResults())
186
+ excludedChild.setOwner(None)
187
+ # Mark dirty to invalidate cache, but suppress the dirtied callback
188
+ # since the node is being detached from the tree and should not
189
+ # propagate dirty signals through external callback mechanisms.
190
+ dirtiedFunc = excludedChild.getDirtiedFunc()
191
+ excludedChild.setDirtiedFunc(None)
192
+ excludedChild.setDirty(True)
193
+ excludedChild.setDirtiedFunc(dirtiedFunc)
194
+ owner.markDirtyAndPropagate()
195
+
196
+
197
+ def YGNodeRemoveAllChildren(ownerRef: YGNodeRef) -> None:
198
+ owner = ownerRef
199
+
200
+ childCount = owner.getChildCount()
201
+ if childCount == 0:
202
+ # This is an empty set already. Nothing to do.
203
+ return
204
+
205
+ firstChild = owner.getChild(0)
206
+ if firstChild.getOwner() == owner:
207
+ # If the first child has this node as its owner, we assume that this child
208
+ # set is unique.
209
+ for index in range(childCount):
210
+ oldChild = owner.getChild(index)
211
+ oldChild.setLayout(LayoutResults())
212
+ oldChild.setOwner(None)
213
+ # Mark dirty to invalidate cache, but suppress the dirtied callback
214
+ # since the node is being detached from the tree and should not
215
+ # propagate dirty signals through external callback mechanisms.
216
+ dirtiedFunc = oldChild.getDirtiedFunc()
217
+ oldChild.setDirtiedFunc(None)
218
+ oldChild.setDirty(True)
219
+ oldChild.setDirtiedFunc(dirtiedFunc)
220
+ owner.clearChildren()
221
+ owner.markDirtyAndPropagate()
222
+ return
223
+
224
+ # Otherwise, we are not the owner of the child set. We don't have to do
225
+ # anything to clear it.
226
+ owner.setChildren([])
227
+ owner.markDirtyAndPropagate()
228
+
229
+
230
+ def YGNodeSetChildren(ownerRef: YGNodeRef, childrenRefs, count: int) -> None:
231
+ owner = ownerRef
232
+ children = [] if childrenRefs is None else list(childrenRefs[:count])
233
+
234
+ if owner is None:
235
+ return
236
+
237
+ if not children:
238
+ if owner.getChildCount() > 0:
239
+ for child in owner.getChildren():
240
+ child.setLayout(LayoutResults())
241
+ child.setOwner(None)
242
+ owner.setChildren([])
243
+ owner.markDirtyAndPropagate()
244
+ else:
245
+ if owner.getChildCount() > 0:
246
+ for oldChild in owner.getChildren():
247
+ # Our new children may have nodes in common with the old children. We
248
+ # don't reset these common nodes.
249
+ if oldChild not in children:
250
+ oldChild.setLayout(LayoutResults())
251
+ oldChild.setOwner(None)
252
+ owner.setChildren(children)
253
+ for child in children:
254
+ child.setOwner(owner)
255
+ owner.markDirtyAndPropagate()
256
+
257
+
258
+ def YGNodeGetChild(nodeRef: YGNodeRef, index: int) -> YGNodeRef | None:
259
+ node = nodeRef
260
+
261
+ if index < node.getChildCount():
262
+ return node.getChild(index)
263
+ return None
264
+
265
+
266
+ def YGNodeGetChildCount(node: YGNodeConstRef) -> int:
267
+ return len(node.getChildren())
268
+
269
+
270
+ def YGNodeGetOwner(node: YGNodeRef):
271
+ return node.getOwner()
272
+
273
+
274
+ def YGNodeGetParent(node: YGNodeRef):
275
+ return node.getOwner()
276
+
277
+
278
+ def YGNodeSetConfig(node: YGNodeRef, config) -> None:
279
+ node.setConfig(config)
280
+
281
+
282
+ def YGNodeGetConfig(node: YGNodeRef):
283
+ return node.getConfig()
284
+
285
+
286
+ def YGNodeSetContext(node: YGNodeRef, context: object) -> None:
287
+ node.setContext(context)
288
+
289
+
290
+ def YGNodeGetContext(node: YGNodeConstRef) -> object:
291
+ return node.getContext()
292
+
293
+
294
+ def YGNodeSetMeasureFunc(node: YGNodeRef, measureFunc) -> None:
295
+ node.setMeasureFunc(measureFunc)
296
+
297
+
298
+ def YGNodeHasMeasureFunc(node: YGNodeConstRef) -> bool:
299
+ return node.hasMeasureFunc()
300
+
301
+
302
+ def YGNodeSetBaselineFunc(node: YGNodeRef, baselineFunc) -> None:
303
+ node.setBaselineFunc(baselineFunc)
304
+
305
+
306
+ def YGNodeHasBaselineFunc(node: YGNodeConstRef) -> bool:
307
+ return node.hasBaselineFunc()
308
+
309
+
310
+ def YGNodeSetIsReferenceBaseline(nodeRef: YGNodeRef, isReferenceBaseline: bool) -> None:
311
+ if nodeRef.isReferenceBaseline() != isReferenceBaseline:
312
+ nodeRef.setIsReferenceBaseline(isReferenceBaseline)
313
+ nodeRef.markDirtyAndPropagate()
314
+
315
+
316
+ def YGNodeIsReferenceBaseline(node: YGNodeConstRef) -> bool:
317
+ return node.isReferenceBaseline()
318
+
319
+
320
+ def YGNodeSetNodeType(node: YGNodeRef, nodeType: YGNodeType) -> None:
321
+ node.setNodeType(nodeType)
322
+
323
+
324
+ def YGNodeGetNodeType(node: YGNodeConstRef) -> YGNodeType:
325
+ return node.getNodeType()
326
+
327
+
328
+ def YGNodeSetAlwaysFormsContainingBlock(node: YGNodeRef, alwaysFormsContainingBlock: bool) -> None:
329
+ node.setAlwaysFormsContainingBlock(alwaysFormsContainingBlock)
330
+
331
+
332
+ def YGNodeGetAlwaysFormsContainingBlock(node: YGNodeConstRef) -> bool:
333
+ return node.alwaysFormsContainingBlock()
334
+
335
+
336
+ # TODO: This leaks internal details to the public API. Remove after removing
337
+ # ComponentKit usage of it.
338
+ def YGNodeCanUseCachedMeasurement(
339
+ widthMode: YGMeasureMode,
340
+ availableWidth: float,
341
+ heightMode: YGMeasureMode,
342
+ availableHeight: float,
343
+ lastWidthMode: YGMeasureMode,
344
+ lastAvailableWidth: float,
345
+ lastHeightMode: YGMeasureMode,
346
+ lastAvailableHeight: float,
347
+ lastComputedWidth: float,
348
+ lastComputedHeight: float,
349
+ marginRow: float,
350
+ marginColumn: float,
351
+ config,
352
+ ) -> bool:
353
+ return canUseCachedMeasurement(
354
+ sizingMode(widthMode),
355
+ availableWidth,
356
+ sizingMode(heightMode),
357
+ availableHeight,
358
+ sizingMode(lastWidthMode),
359
+ lastAvailableWidth,
360
+ sizingMode(lastHeightMode),
361
+ lastAvailableHeight,
362
+ lastComputedWidth,
363
+ lastComputedHeight,
364
+ marginRow,
365
+ marginColumn,
366
+ config,
367
+ )
yoga/YGNodeLayout.py ADDED
@@ -0,0 +1,81 @@
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 .YGEnums import YGDimension, YGDirection, YGEdge
11
+ from .node.Node import Node
12
+
13
+
14
+ def _getResolvedLayoutProperty(node: Node, edge: YGEdge, member: str) -> float:
15
+ if edge > YGEdge.YGEdgeEnd:
16
+ raise ValueError("Cannot get layout properties of multi-edge shorthands")
17
+
18
+ layout = node.getLayout()
19
+ if edge == YGEdge.YGEdgeStart:
20
+ if layout.direction() == YGDirection.YGDirectionRTL:
21
+ return getattr(layout, member)(YGEdge.YGEdgeRight)
22
+ return getattr(layout, member)(YGEdge.YGEdgeLeft)
23
+
24
+ if edge == YGEdge.YGEdgeEnd:
25
+ if layout.direction() == YGDirection.YGDirectionRTL:
26
+ return getattr(layout, member)(YGEdge.YGEdgeLeft)
27
+ return getattr(layout, member)(YGEdge.YGEdgeRight)
28
+
29
+ return getattr(layout, member)(edge)
30
+
31
+
32
+ def YGNodeLayoutGetLeft(node: Node) -> float:
33
+ return node.getLayout().position(YGEdge.YGEdgeLeft)
34
+
35
+
36
+ def YGNodeLayoutGetTop(node: Node) -> float:
37
+ return node.getLayout().position(YGEdge.YGEdgeTop)
38
+
39
+
40
+ def YGNodeLayoutGetRight(node: Node) -> float:
41
+ return node.getLayout().position(YGEdge.YGEdgeRight)
42
+
43
+
44
+ def YGNodeLayoutGetBottom(node: Node) -> float:
45
+ return node.getLayout().position(YGEdge.YGEdgeBottom)
46
+
47
+
48
+ def YGNodeLayoutGetWidth(node: Node) -> float:
49
+ return node.getLayout().dimension(YGDimension.YGDimensionWidth)
50
+
51
+
52
+ def YGNodeLayoutGetHeight(node: Node) -> float:
53
+ return node.getLayout().dimension(YGDimension.YGDimensionHeight)
54
+
55
+
56
+ def YGNodeLayoutGetDirection(node: Node) -> YGDirection:
57
+ return node.getLayout().direction()
58
+
59
+
60
+ def YGNodeLayoutGetHadOverflow(node: Node) -> bool:
61
+ return node.getLayout().hadOverflow()
62
+
63
+
64
+ def YGNodeLayoutGetMargin(node: Node, edge: YGEdge) -> float:
65
+ return _getResolvedLayoutProperty(node, edge, "margin")
66
+
67
+
68
+ def YGNodeLayoutGetBorder(node: Node, edge: YGEdge) -> float:
69
+ return _getResolvedLayoutProperty(node, edge, "border")
70
+
71
+
72
+ def YGNodeLayoutGetPadding(node: Node, edge: YGEdge) -> float:
73
+ return _getResolvedLayoutProperty(node, edge, "padding")
74
+
75
+
76
+ def YGNodeLayoutGetRawHeight(node: Node) -> float:
77
+ return node.getLayout().rawDimension(YGDimension.YGDimensionHeight)
78
+
79
+
80
+ def YGNodeLayoutGetRawWidth(node: Node) -> float:
81
+ return node.getLayout().rawDimension(YGDimension.YGDimensionWidth)