tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 501HTML 254C 19JavaScript 81414 Definiciones

⎇ bce89b1006f36ce35abfaf1f1c2b3dd95f3dffd3 bindings/swift/StretchKit/Classes/Node.swift 117 líneas · 3.5 KB Historia crudo

Implement new rust API for bindings and release v0.3 bce89b100 · Emil Sjölander ·

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}