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
@@ -0,0 +1,76 @@
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 ..debug.AssertFatal import fatalWithMessage
11
+ from ..YGEnums import YGDimension, YGDirection, YGEdge, YGFlexDirection
12
+
13
+
14
+ def isRow(flexDirection: YGFlexDirection) -> bool:
15
+ return flexDirection in (YGFlexDirection.YGFlexDirectionRow, YGFlexDirection.YGFlexDirectionRowReverse)
16
+
17
+
18
+ def isColumn(flexDirection: YGFlexDirection) -> bool:
19
+ return flexDirection in (YGFlexDirection.YGFlexDirectionColumn, YGFlexDirection.YGFlexDirectionColumnReverse)
20
+
21
+
22
+ def resolveDirection(flexDirection: YGFlexDirection, direction: YGDirection) -> YGFlexDirection:
23
+ if direction == YGDirection.YGDirectionRTL:
24
+ if flexDirection == YGFlexDirection.YGFlexDirectionRow:
25
+ return YGFlexDirection.YGFlexDirectionRowReverse
26
+ if flexDirection == YGFlexDirection.YGFlexDirectionRowReverse:
27
+ return YGFlexDirection.YGFlexDirectionRow
28
+ return flexDirection
29
+
30
+
31
+ def resolveCrossDirection(flexDirection: YGFlexDirection, direction: YGDirection) -> YGFlexDirection:
32
+ return resolveDirection(YGFlexDirection.YGFlexDirectionRow, direction) if isColumn(flexDirection) else YGFlexDirection.YGFlexDirectionColumn
33
+
34
+
35
+ def flexStartEdge(flexDirection: YGFlexDirection) -> YGEdge:
36
+ if flexDirection == YGFlexDirection.YGFlexDirectionColumn:
37
+ return YGEdge.YGEdgeTop
38
+ if flexDirection == YGFlexDirection.YGFlexDirectionColumnReverse:
39
+ return YGEdge.YGEdgeBottom
40
+ if flexDirection == YGFlexDirection.YGFlexDirectionRow:
41
+ return YGEdge.YGEdgeLeft
42
+ if flexDirection == YGFlexDirection.YGFlexDirectionRowReverse:
43
+ return YGEdge.YGEdgeRight
44
+ fatalWithMessage("Invalid FlexDirection")
45
+
46
+
47
+ def flexEndEdge(flexDirection: YGFlexDirection) -> YGEdge:
48
+ if flexDirection == YGFlexDirection.YGFlexDirectionColumn:
49
+ return YGEdge.YGEdgeBottom
50
+ if flexDirection == YGFlexDirection.YGFlexDirectionColumnReverse:
51
+ return YGEdge.YGEdgeTop
52
+ if flexDirection == YGFlexDirection.YGFlexDirectionRow:
53
+ return YGEdge.YGEdgeRight
54
+ if flexDirection == YGFlexDirection.YGFlexDirectionRowReverse:
55
+ return YGEdge.YGEdgeLeft
56
+ fatalWithMessage("Invalid FlexDirection")
57
+
58
+
59
+ def inlineStartEdge(flexDirection: YGFlexDirection, direction: YGDirection) -> YGEdge:
60
+ if isRow(flexDirection):
61
+ return YGEdge.YGEdgeRight if direction == YGDirection.YGDirectionRTL else YGEdge.YGEdgeLeft
62
+ return YGEdge.YGEdgeTop
63
+
64
+
65
+ def inlineEndEdge(flexDirection: YGFlexDirection, direction: YGDirection) -> YGEdge:
66
+ if isRow(flexDirection):
67
+ return YGEdge.YGEdgeLeft if direction == YGDirection.YGDirectionRTL else YGEdge.YGEdgeRight
68
+ return YGEdge.YGEdgeBottom
69
+
70
+
71
+ def dimension(flexDirection: YGFlexDirection) -> YGDimension:
72
+ if flexDirection in (YGFlexDirection.YGFlexDirectionColumn, YGFlexDirection.YGFlexDirectionColumnReverse):
73
+ return YGDimension.YGDimensionHeight
74
+ if flexDirection in (YGFlexDirection.YGFlexDirectionRow, YGFlexDirection.YGFlexDirectionRowReverse):
75
+ return YGDimension.YGDimensionWidth
76
+ fatalWithMessage("Invalid FlexDirection")
@@ -0,0 +1,130 @@
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 dataclasses import dataclass, field
11
+
12
+ from ..algorithm.BoundAxis import boundAxisWithinMinAndMax
13
+ from ..algorithm.FlexDirection import resolveDirection
14
+ from ..numeric.FloatMath import float32
15
+ from ..YGEnums import YGDirection, YGDisplay, YGPositionType, YGWrap
16
+
17
+
18
+ @dataclass
19
+ class FlexLineRunningLayout:
20
+ totalFlexGrowFactors: float = 0.0
21
+ totalFlexShrinkScaledFactors: float = 0.0
22
+ remainingFreeSpace: float = 0.0
23
+ mainDim: float = 0.0
24
+ crossDim: float = 0.0
25
+
26
+
27
+ @dataclass
28
+ class FlexLine:
29
+ itemsInFlow: list = field(default_factory=list)
30
+ sizeConsumed: float = 0.0
31
+ numberOfAutoMargins: int = 0
32
+ layout: FlexLineRunningLayout = field(default_factory=FlexLineRunningLayout)
33
+
34
+
35
+ def calculateFlexLine(
36
+ node,
37
+ ownerDirection: YGDirection,
38
+ ownerWidth: float,
39
+ mainAxisOwnerSize: float,
40
+ availableInnerWidth: float,
41
+ availableInnerMainDim: float,
42
+ children,
43
+ startIndex: int,
44
+ lineCount: int,
45
+ ) -> FlexLine:
46
+ itemsInFlow = []
47
+ sizeConsumed = float32(0.0)
48
+ totalFlexGrowFactors = 0.0
49
+ totalFlexShrinkScaledFactors = 0.0
50
+ numberOfAutoMargins = 0
51
+ firstElementInLine = None
52
+ sizeConsumedIncludingMinConstraint = float32(0.0)
53
+ direction = node.resolveDirection(ownerDirection)
54
+ mainAxis = resolveDirection(node.style().flexDirection(), direction)
55
+ isNodeFlexWrap = node.style().flexWrap() != YGWrap.YGWrapNoWrap
56
+ gap = node.style().computeGapForAxis(mainAxis, availableInnerMainDim)
57
+
58
+ for child in children[startIndex:]:
59
+ if child.style().display() == YGDisplay.YGDisplayNone or child.style().positionType() == YGPositionType.YGPositionTypeAbsolute:
60
+ continue
61
+ if firstElementInLine is None:
62
+ firstElementInLine = child
63
+ if child.style().flexStartMarginIsAuto(mainAxis, ownerDirection):
64
+ numberOfAutoMargins += 1
65
+ if child.style().flexEndMarginIsAuto(mainAxis, ownerDirection):
66
+ numberOfAutoMargins += 1
67
+ child.setLineIndex(lineCount)
68
+ childMarginMainAxis = child.style().computeMarginForAxis(mainAxis, availableInnerWidth)
69
+ childLeadingGapMainAxis = 0.0 if child == firstElementInLine else gap
70
+ flexBasisWithMinAndMaxConstraints = boundAxisWithinMinAndMax(
71
+ child,
72
+ direction,
73
+ mainAxis,
74
+ child.getLayout().computedFlexBasis,
75
+ mainAxisOwnerSize,
76
+ ownerWidth,
77
+ ).unwrap()
78
+ if (
79
+ sizeConsumedIncludingMinConstraint
80
+ + flexBasisWithMinAndMaxConstraints
81
+ + childMarginMainAxis
82
+ + childLeadingGapMainAxis
83
+ > availableInnerMainDim
84
+ and isNodeFlexWrap
85
+ and itemsInFlow
86
+ ):
87
+ break
88
+ sizeConsumedIncludingMinConstraint = float32(
89
+ sizeConsumedIncludingMinConstraint
90
+ + float32(
91
+ flexBasisWithMinAndMaxConstraints
92
+ + childMarginMainAxis
93
+ + childLeadingGapMainAxis
94
+ )
95
+ )
96
+ sizeConsumed = float32(
97
+ sizeConsumed
98
+ + float32(
99
+ flexBasisWithMinAndMaxConstraints
100
+ + childMarginMainAxis
101
+ + childLeadingGapMainAxis
102
+ )
103
+ )
104
+ if child.isNodeFlexible():
105
+ totalFlexGrowFactors = float32(
106
+ totalFlexGrowFactors + child.resolveFlexGrow()
107
+ )
108
+ totalFlexShrinkScaledFactors = float32(
109
+ totalFlexShrinkScaledFactors
110
+ + float32(
111
+ -child.resolveFlexShrink()
112
+ * child.getLayout().computedFlexBasis.unwrap()
113
+ )
114
+ )
115
+ itemsInFlow.append(child)
116
+
117
+ if 0 < totalFlexGrowFactors < 1:
118
+ totalFlexGrowFactors = 1
119
+ if 0 < totalFlexShrinkScaledFactors < 1:
120
+ totalFlexShrinkScaledFactors = 1
121
+
122
+ return FlexLine(
123
+ itemsInFlow=itemsInFlow,
124
+ sizeConsumed=sizeConsumed,
125
+ numberOfAutoMargins=numberOfAutoMargins,
126
+ layout=FlexLineRunningLayout(
127
+ totalFlexGrowFactors=totalFlexGrowFactors,
128
+ totalFlexShrinkScaledFactors=totalFlexShrinkScaledFactors,
129
+ ),
130
+ )
@@ -0,0 +1,56 @@
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
+ import math
11
+
12
+ from ..numeric.Comparison import inexactEquals, isUndefined
13
+ from ..YGEnums import YGDimension, YGEdge, YGNodeType
14
+ from ..YGPixelGrid import YGRoundValueToPixelGrid as roundValueToPixelGrid
15
+
16
+
17
+ def roundLayoutResultsToPixelGrid(node, absoluteLeft: float, absoluteTop: float) -> None:
18
+ pointScaleFactor = float(node.getConfig().getPointScaleFactor())
19
+ nodeLeft = node.getLayout().position(YGEdge.YGEdgeLeft)
20
+ nodeTop = node.getLayout().position(YGEdge.YGEdgeTop)
21
+ nodeWidth = node.getLayout().dimension(YGDimension.YGDimensionWidth)
22
+ nodeHeight = node.getLayout().dimension(YGDimension.YGDimensionHeight)
23
+ absoluteNodeLeft = absoluteLeft + nodeLeft
24
+ absoluteNodeTop = absoluteTop + nodeTop
25
+ absoluteNodeRight = absoluteNodeLeft + nodeWidth
26
+ absoluteNodeBottom = absoluteNodeTop + nodeHeight
27
+ if pointScaleFactor != 0.0:
28
+ textRounding = node.getNodeType() == YGNodeType.YGNodeTypeText
29
+ node.setLayoutPosition(roundValueToPixelGrid(nodeLeft, pointScaleFactor, False, textRounding), YGEdge.YGEdgeLeft)
30
+ node.setLayoutPosition(roundValueToPixelGrid(nodeTop, pointScaleFactor, False, textRounding), YGEdge.YGEdgeTop)
31
+ if not isUndefined(nodeWidth):
32
+ scaledNodeWidth = nodeWidth * pointScaleFactor
33
+ hasFractionalWidth = (
34
+ not inexactEquals(round(scaledNodeWidth), scaledNodeWidth)
35
+ if math.isfinite(scaledNodeWidth)
36
+ else False
37
+ )
38
+ node.getLayout().setDimension(
39
+ YGDimension.YGDimensionWidth,
40
+ roundValueToPixelGrid(absoluteNodeRight, pointScaleFactor, textRounding and hasFractionalWidth, textRounding and not hasFractionalWidth)
41
+ - roundValueToPixelGrid(absoluteNodeLeft, pointScaleFactor, False, textRounding),
42
+ )
43
+ if not isUndefined(nodeHeight):
44
+ scaledNodeHeight = nodeHeight * pointScaleFactor
45
+ hasFractionalHeight = (
46
+ not inexactEquals(round(scaledNodeHeight), scaledNodeHeight)
47
+ if math.isfinite(scaledNodeHeight)
48
+ else False
49
+ )
50
+ node.getLayout().setDimension(
51
+ YGDimension.YGDimensionHeight,
52
+ roundValueToPixelGrid(absoluteNodeBottom, pointScaleFactor, textRounding and hasFractionalHeight, textRounding and not hasFractionalHeight)
53
+ - roundValueToPixelGrid(absoluteNodeTop, pointScaleFactor, False, textRounding),
54
+ )
55
+ for child in node.getChildren():
56
+ roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop)
@@ -0,0 +1,39 @@
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 enum import Enum
11
+
12
+ from ..debug.AssertFatal import fatalWithMessage
13
+ from ..YGEnums import YGMeasureMode
14
+
15
+
16
+ class SizingMode(Enum):
17
+ StretchFit = 0
18
+ MaxContent = 1
19
+ FitContent = 2
20
+
21
+
22
+ def measureMode(mode: SizingMode) -> YGMeasureMode:
23
+ if mode == SizingMode.StretchFit:
24
+ return YGMeasureMode.YGMeasureModeExactly
25
+ if mode == SizingMode.MaxContent:
26
+ return YGMeasureMode.YGMeasureModeUndefined
27
+ if mode == SizingMode.FitContent:
28
+ return YGMeasureMode.YGMeasureModeAtMost
29
+ fatalWithMessage("Invalid SizingMode")
30
+
31
+
32
+ def sizingMode(mode: YGMeasureMode) -> SizingMode:
33
+ if mode == YGMeasureMode.YGMeasureModeExactly:
34
+ return SizingMode.StretchFit
35
+ if mode == YGMeasureMode.YGMeasureModeUndefined:
36
+ return SizingMode.MaxContent
37
+ if mode == YGMeasureMode.YGMeasureModeAtMost:
38
+ return SizingMode.FitContent
39
+ fatalWithMessage("Invalid MeasureMode")
@@ -0,0 +1,34 @@
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 ..algorithm.FlexDirection import dimension, flexEndEdge, flexStartEdge
11
+ from ..numeric.FloatMath import float32
12
+ from ..YGEnums import YGFlexDirection
13
+ from ..node.Node import Node
14
+
15
+
16
+ def getPositionOfOppositeEdge(position: float, axis: YGFlexDirection, containingNode: Node, node: Node) -> float:
17
+ return float32(
18
+ float32(
19
+ float32(containingNode.getLayout().measuredDimension(dimension(axis)))
20
+ - float32(node.getLayout().measuredDimension(dimension(axis)))
21
+ )
22
+ - float32(position)
23
+ )
24
+
25
+
26
+ def setChildTrailingPosition(node: Node, child: Node, axis: YGFlexDirection) -> None:
27
+ child.setLayoutPosition(
28
+ getPositionOfOppositeEdge(child.getLayout().position(flexStartEdge(axis)), axis, node, child),
29
+ flexEndEdge(axis),
30
+ )
31
+
32
+
33
+ def needsTrailingPosition(axis: YGFlexDirection) -> bool:
34
+ return axis in (YGFlexDirection.YGFlexDirectionRowReverse, YGFlexDirection.YGFlexDirectionColumnReverse)
@@ -0,0 +1,18 @@
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 .AbsoluteLayout import *
9
+ from .Align import *
10
+ from .Baseline import *
11
+ from .BoundAxis import *
12
+ from .Cache import *
13
+ from .CalculateLayout import *
14
+ from .FlexLine import *
15
+ from .FlexDirection import *
16
+ from .PixelGrid import *
17
+ from .SizingMode import *
18
+ from .TrailingPosition import *
yoga/config/Config.py ADDED
@@ -0,0 +1,137 @@
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 dataclasses import dataclass, field
11
+ from typing import Any, Callable
12
+
13
+ from ..YGEnums import YGErrata, YGExperimentalFeature, YGLogLevel
14
+
15
+
16
+ YGLogger = Callable[..., int]
17
+ YGCloneNodeFunc = Callable[..., Any]
18
+
19
+
20
+ def _default_logger(*_args: object, **_kwargs: object) -> int:
21
+ return 0
22
+
23
+
24
+ @dataclass
25
+ class Config:
26
+ cloneNodeCallback_: YGCloneNodeFunc | None = None
27
+ logger_: YGLogger = _default_logger
28
+ useWebDefaults_: bool = False
29
+ version_: int = 0
30
+ experimentalFeatures_: dict[YGExperimentalFeature, bool] = field(
31
+ default_factory=dict
32
+ )
33
+ errata_: YGErrata = YGErrata.YGErrataNone
34
+ pointScaleFactor_: float = 1.0
35
+ context_: Any = None
36
+
37
+ def setUseWebDefaults(self, useWebDefaults: bool) -> None:
38
+ self.useWebDefaults_ = useWebDefaults
39
+
40
+ def useWebDefaults(self) -> bool:
41
+ return self.useWebDefaults_
42
+
43
+ def setExperimentalFeatureEnabled(
44
+ self, feature: YGExperimentalFeature, enabled: bool
45
+ ) -> None:
46
+ if self.isExperimentalFeatureEnabled(feature) != enabled:
47
+ self.experimentalFeatures_[feature] = enabled
48
+ self.version_ += 1
49
+
50
+ def isExperimentalFeatureEnabled(self, feature: YGExperimentalFeature) -> bool:
51
+ return self.experimentalFeatures_.get(feature, False)
52
+
53
+ def getEnabledExperiments(self) -> dict[YGExperimentalFeature, bool]:
54
+ return dict(self.experimentalFeatures_)
55
+
56
+ def setErrata(self, errata: YGErrata) -> None:
57
+ if self.errata_ != errata:
58
+ self.errata_ = errata
59
+ self.version_ += 1
60
+
61
+ def addErrata(self, errata: YGErrata) -> None:
62
+ if not self.hasErrata(errata):
63
+ self.errata_ |= errata
64
+ self.version_ += 1
65
+
66
+ def removeErrata(self, errata: YGErrata) -> None:
67
+ if self.hasErrata(errata):
68
+ self.errata_ &= ~errata
69
+ self.version_ += 1
70
+
71
+ def getErrata(self) -> YGErrata:
72
+ return self.errata_
73
+
74
+ def hasErrata(self, errata: YGErrata) -> bool:
75
+ return bool(self.errata_ & errata)
76
+
77
+ def setPointScaleFactor(self, pointScaleFactor: float) -> None:
78
+ if self.pointScaleFactor_ != pointScaleFactor:
79
+ self.pointScaleFactor_ = pointScaleFactor
80
+ self.version_ += 1
81
+
82
+ def getPointScaleFactor(self) -> float:
83
+ return self.pointScaleFactor_
84
+
85
+ def setContext(self, context: Any) -> None:
86
+ self.context_ = context
87
+
88
+ def getContext(self) -> Any:
89
+ return self.context_
90
+
91
+ def getVersion(self) -> int:
92
+ return self.version_
93
+
94
+ def setLogger(self, logger: YGLogger) -> None:
95
+ self.logger_ = logger
96
+
97
+ def log(
98
+ self,
99
+ node: object,
100
+ logLevel: YGLogLevel,
101
+ format_string: str,
102
+ args: tuple[object, ...] = (),
103
+ ) -> int:
104
+ return self.logger_(self, node, logLevel, format_string, args)
105
+
106
+ def setCloneNodeCallback(self, cloneNode: YGCloneNodeFunc | None) -> None:
107
+ self.cloneNodeCallback_ = cloneNode
108
+
109
+ def cloneNode(self, node: object, owner: object, childIndex: int) -> object:
110
+ clone = None
111
+ if self.cloneNodeCallback_ is not None:
112
+ clone = self.cloneNodeCallback_(node, owner, childIndex)
113
+ if clone is None:
114
+ from ..YGNode import YGNodeClone
115
+
116
+ clone = YGNodeClone(node)
117
+ return clone
118
+
119
+
120
+ _DEFAULT_CONFIG = Config()
121
+
122
+
123
+ def configUpdateInvalidatesLayout(oldConfig: Config, newConfig: Config) -> bool:
124
+ return (
125
+ oldConfig.getErrata() != newConfig.getErrata()
126
+ or oldConfig.getPointScaleFactor() != newConfig.getPointScaleFactor()
127
+ or oldConfig.useWebDefaults() != newConfig.useWebDefaults()
128
+ or oldConfig.getEnabledExperiments() != newConfig.getEnabledExperiments()
129
+ )
130
+
131
+
132
+ def resolveRef(ref: Config | None) -> Config | None:
133
+ return ref
134
+
135
+
136
+ def getDefaultConfig() -> Config:
137
+ return _DEFAULT_CONFIG
@@ -0,0 +1,9 @@
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 .Config import *
9
+
@@ -0,0 +1,24 @@
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
+
9
+ def assertFatal(condition: bool, message: str) -> None:
10
+ if not condition:
11
+ raise AssertionError(message)
12
+
13
+
14
+ def assertFatalWithConfig(_config, condition: bool, message: str) -> None:
15
+ assertFatal(condition, message)
16
+
17
+
18
+ def assertFatalWithNode(_node, condition: bool, message: str) -> None:
19
+ assertFatal(condition, message)
20
+
21
+
22
+ def fatalWithMessage(message: str) -> None:
23
+ raise RuntimeError(message)
24
+
yoga/debug/Log.py ADDED
@@ -0,0 +1,49 @@
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 typing import Any
11
+
12
+ from ..YGEnums import YGLogLevel
13
+
14
+
15
+ def getDefaultLogger():
16
+ """Get the default logger that does nothing."""
17
+ def _logger(*_args: object, **_kwargs: object) -> int:
18
+ return 0
19
+ return _logger
20
+
21
+
22
+ def log(node: Any | None, level: YGLogLevel, format_string: str, *args: object) -> int:
23
+ """
24
+ Log a message at the given level.
25
+
26
+ Args:
27
+ node: The yoga node (can be None)
28
+ level: The log level
29
+ format_string: The format string
30
+ *args: Arguments to format into the string
31
+ """
32
+ if node is None:
33
+ # Log without node
34
+ logger = getDefaultLogger()
35
+ return logger(None, None, level, format_string, args)
36
+
37
+ config = node.getConfig() if node is not None else None
38
+ logger = config.logger_ if config is not None else getDefaultLogger()
39
+ return logger(config, node, level, format_string, args)
40
+
41
+
42
+ def logWithConfig(config: Any | None, level: YGLogLevel, format_string: str, *args: object) -> int:
43
+ """Log a message with a config but no node."""
44
+ if config is None:
45
+ logger = getDefaultLogger()
46
+ return logger(None, None, level, format_string, args)
47
+ logger = config.logger_ if hasattr(config, 'logger_') else getDefaultLogger()
48
+ return logger(config, None, level, format_string, args)
49
+
yoga/debug/__init__.py ADDED
@@ -0,0 +1,10 @@
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 .AssertFatal import *
9
+ from .Log import *
10
+
yoga/event/__init__.py ADDED
@@ -0,0 +1,9 @@
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 .event import *
9
+