|
1 | 1 | use super::{ |
2 | | - bail, bail_if_null, ok, try_or, TaffyFFIDefault, TaffyFFIResult, TaffyLayout, TaffyResult, TaffyReturnCode, |
3 | | - TaffyStyleMutRef, |
| 2 | + bail, bail_if_null, ok, try_or, TaffyFFIDefault, TaffyFFIResult, TaffyLayout, TaffyMeasureMode, TaffyResult, |
| 3 | + TaffyReturnCode, TaffySize, TaffyStyleMutRef, |
4 | 4 | }; |
| 5 | +use ::core::ffi::c_void; |
5 | 6 | use taffy::prelude as core; |
| 7 | +use taffy::style::AvailableSpace; |
6 | 8 | use taffy::Taffy as CoreTaffy; |
7 | 9 |
|
| 10 | +pub type TaffyMeasureFunction = extern "C" fn( |
| 11 | + width_measure_mode: TaffyMeasureMode, |
| 12 | + width: f32, |
| 13 | + height_measure_mode: TaffyMeasureMode, |
| 14 | + height: f32, |
| 15 | + context: *mut c_void, |
| 16 | +) -> TaffySize; |
| 17 | + |
| 18 | +#[allow(dead_code)] // false positive |
| 19 | +struct NodeContext { |
| 20 | + context: *mut c_void, |
| 21 | + measure_function: TaffyMeasureFunction, |
| 22 | +} |
| 23 | + |
8 | 24 | pub struct TaffyTree { |
9 | | - inner: CoreTaffy, |
| 25 | + inner: CoreTaffy<NodeContext>, |
10 | 26 | } |
11 | 27 | pub type TaffyTreeOwnedRef = *mut TaffyTree; |
12 | 28 | pub type TaffyTreeMutRef = *mut TaffyTree; |
@@ -94,7 +110,33 @@ pub unsafe extern "C" fn TaffyTree_ComputeLayout( |
94 | 110 | width: available_space_from_f32(available_width), |
95 | 111 | height: available_space_from_f32(available_height), |
96 | 112 | }; |
97 | | - try_or!(InvalidNodeId, tree.inner.compute_layout(node_id.into(), available_space)); |
| 113 | + try_or!( |
| 114 | + InvalidNodeId, |
| 115 | + tree.inner.compute_layout_with_measure( |
| 116 | + node_id.into(), |
| 117 | + available_space, |
| 118 | + |known_dimensions, available_space, _node_id, node_context| { |
| 119 | + let (width, width_measure_mode) = match (known_dimensions.width, available_space.width) { |
| 120 | + (Some(width), _) => (width, TaffyMeasureMode::Exact), |
| 121 | + (None, AvailableSpace::Definite(width)) => (width, TaffyMeasureMode::FitContent), |
| 122 | + (None, AvailableSpace::MaxContent) => (f32::INFINITY, TaffyMeasureMode::MaxContent), |
| 123 | + (None, AvailableSpace::MinContent) => (f32::INFINITY, TaffyMeasureMode::MinContent), |
| 124 | + }; |
| 125 | + let (height, height_measure_mode) = match (known_dimensions.height, available_space.height) { |
| 126 | + (Some(height), _) => (height, TaffyMeasureMode::Exact), |
| 127 | + (None, AvailableSpace::Definite(height)) => (height, TaffyMeasureMode::FitContent), |
| 128 | + (None, AvailableSpace::MaxContent) => (f32::INFINITY, TaffyMeasureMode::MaxContent), |
| 129 | + (None, AvailableSpace::MinContent) => (f32::INFINITY, TaffyMeasureMode::MinContent), |
| 130 | + }; |
| 131 | + match node_context { |
| 132 | + Some(NodeContext { measure_function, context }) => { |
| 133 | + measure_function(width_measure_mode, width, height_measure_mode, height, *context).into() |
| 134 | + } |
| 135 | + _ => core::Size::ZERO, |
| 136 | + } |
| 137 | + } |
| 138 | + ) |
| 139 | + ); |
98 | 140 | TaffyReturnCode::Ok |
99 | 141 | }) |
100 | 142 | } |
@@ -165,6 +207,24 @@ pub unsafe extern "C" fn TaffyTree_GetStyleMut( |
165 | 207 | }) |
166 | 208 | } |
167 | 209 |
|
| 210 | +/// Create a new Node in the TaffyTree. Returns a NodeId handle to the node. |
| 211 | +#[no_mangle] |
| 212 | +#[allow(clippy::missing_safety_doc)] |
| 213 | +pub unsafe extern "C" fn TaffyTree_SetNodeContext( |
| 214 | + raw_tree: TaffyTreeMutRef, |
| 215 | + node_id: TaffyNodeId, |
| 216 | + measure_function: TaffyMeasureFunction, |
| 217 | + context: *mut c_void, |
| 218 | +) -> TaffyReturnCode { |
| 219 | + with_tree_mut!(raw_tree, tree, { |
| 220 | + try_or!( |
| 221 | + InvalidNodeId, |
| 222 | + tree.inner.set_node_context(node_id.into(), Some(NodeContext { measure_function, context })) |
| 223 | + ); |
| 224 | + ok!(TaffyReturnCode::Ok); |
| 225 | + }) |
| 226 | +} |
| 227 | + |
168 | 228 | /// Create a new Node in the TaffyTree. Returns a NodeId handle to the node. |
169 | 229 | #[no_mangle] |
170 | 230 | #[allow(clippy::missing_safety_doc)] |
|
0 commit comments