Implement new rust API for bindings and release v0.3
1import Foundation
2
3private func node_measure(_ node: UnsafeRawPointer?, _ width: Float, _ height: Float) -> StretchSize {
4 let node: Node = Unmanaged.fromOpaque(node!).takeUnretainedValue()
5 let size = node.measure!(Size(width: width.isNaN ? nil : width, height: height.isNaN ? nil : height))
6 return StretchSize(width: size.width, height: size.height)
7}
8
9private func create_layout(_ floats: UnsafePointer<Float>?) -> UnsafeMutableRawPointer? {
10 let layout = Layout.fromFloats(floats!).1
11 return Unmanaged.passRetained(layout).toOpaque()
12}
13
14public typealias MeasureFunc = (Size<Float?>) -> Size<Float>
15
16fileprivate let stretchptr = stretch_init()
17
18public class Node {
19 private let rustptr: UnsafeMutableRawPointer
20 private var _children: Array<Node> = []
21 private var _measure: MeasureFunc? = nil
22
23 public var style: Style {
24 willSet(style) {
25 stretch_node_set_style(stretchptr, rustptr, style.rustptr)
26 }
27 }
28
29 public var children: Array<Node> {
30 get {
31 return self._children
32 }
33 set {
34 let num_children = _children.count
35 for i in 0..<num_children {
36 removeChild(at: num_children - 1 - i)
37 }
38
39 for child in newValue {
40 addChild(child)
41 }
42 }
43 }
44
45 public var measure: MeasureFunc? {
46 get {
47 return self._measure
48 }
49 set {
50 self._measure = newValue
51 stretch_node_set_measure(stretchptr, rustptr, Unmanaged.passRetained(self).toOpaque(), node_measure)
52 }
53 }
54
55 public init(style: Style, measure: @escaping MeasureFunc) {
56 self.rustptr = stretch_node_create(stretchptr, style.rustptr)
57 self.style = style
58 self.measure = measure
59 }
60
61 public init(style: Style, children: Array<Node>) {
62 self.rustptr = stretch_node_create(stretchptr, style.rustptr)
63 self.style = style
64 self.children = children
65 }
66
67 deinit {
68 stretch_node_free(stretchptr, rustptr)
69 }
70
71 public func addChild(_ child: Node) {
72 stretch_node_add_child(stretchptr, rustptr, child.rustptr)
73 _children.append(child)
74 }
75
76 @discardableResult
77 public func replaceChild(_ child: Node, at index: Int) -> Node {
78 stretch_node_replace_child_at_index(stretchptr, rustptr, UInt(index), child.rustptr)
79 let oldChild = _children[index]
80 _children[index] = child
81 return oldChild
82 }
83
84 @discardableResult
85 public func removeChild(_ child: Node) -> Node {
86 stretch_node_remove_child(stretchptr, rustptr, child.rustptr)
87 _children.removeAll { (node) -> Bool in
88 return node === child
89 }
90 return child
91 }
92
93 @discardableResult
94 public func removeChild(at index: Int) -> Node {
95 stretch_node_remove_child_at_index(stretchptr, rustptr, UInt(index))
96 return _children.remove(at: index)
97 }
98
99 public func markDirty() {
100 stretch_node_mark_dirty(stretchptr, rustptr)
101 }
102
103 public var dirty: Bool {
104 return stretch_node_dirty(stretchptr, rustptr)
105 }
106
107 public func computeLayout(thatFits size: Size<Float?>) -> Layout {
108 let layoutPtr = stretch_node_compute_layout(
109 stretchptr,
110 rustptr,
111 size.width ?? Float.nan,
112 size.height ?? Float.nan,
113 create_layout)
114 let layout: Layout = Unmanaged.fromOpaque(layoutPtr!).takeUnretainedValue()
115 return layout
116 }
117}