Skip to content

Commit 2a7cc5a

Browse files
committed
Add ability to set measure function
1 parent 1494b27 commit 2a7cc5a

File tree

2 files changed

+93
-4
lines changed

2 files changed

+93
-4
lines changed

ctaffy/src/tree.rs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
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,
44
};
5+
use ::core::ffi::c_void;
56
use taffy::prelude as core;
7+
use taffy::style::AvailableSpace;
68
use taffy::Taffy as CoreTaffy;
79

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+
824
pub struct TaffyTree {
9-
inner: CoreTaffy,
25+
inner: CoreTaffy<NodeContext>,
1026
}
1127
pub type TaffyTreeOwnedRef = *mut TaffyTree;
1228
pub type TaffyTreeMutRef = *mut TaffyTree;
@@ -94,7 +110,33 @@ pub unsafe extern "C" fn TaffyTree_ComputeLayout(
94110
width: available_space_from_f32(available_width),
95111
height: available_space_from_f32(available_height),
96112
};
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+
);
98140
TaffyReturnCode::Ok
99141
})
100142
}
@@ -165,6 +207,24 @@ pub unsafe extern "C" fn TaffyTree_GetStyleMut(
165207
})
166208
}
167209

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+
168228
/// Create a new Node in the TaffyTree. Returns a NodeId handle to the node.
169229
#[no_mangle]
170230
#[allow(clippy::missing_safety_doc)]

ctaffy/src/value.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,35 @@ pub enum TaffyUnit {
4646
Fr,
4747
}
4848

49+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50+
#[repr(C)]
51+
pub enum TaffyMeasureMode {
52+
/// A none value (used to unset optional fields)
53+
Exact,
54+
/// Fixed Length (pixel) value
55+
FitContent,
56+
/// Percentage value
57+
MinContent,
58+
/// Min-content size
59+
MaxContent,
60+
}
61+
62+
#[derive(Debug, Clone, Copy)]
63+
#[repr(C)]
64+
pub struct TaffySize {
65+
width: f32,
66+
height: f32,
67+
}
68+
impl From<TaffySize> for core::Size<f32> {
69+
#[inline(always)]
70+
fn from(value: TaffySize) -> Self {
71+
core::Size {
72+
width: value.width,
73+
height: value.height,
74+
}
75+
}
76+
}
77+
4978
#[repr(C)]
5079
pub struct TaffyLayout {
5180
pub x: f32,

0 commit comments

Comments
 (0)