Skip to content

Commit

Permalink
Add ability to set measure function
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed Oct 22, 2023
1 parent 1494b27 commit 2a7cc5a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 4 deletions.
68 changes: 64 additions & 4 deletions ctaffy/src/tree.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
use super::{
bail, bail_if_null, ok, try_or, TaffyFFIDefault, TaffyFFIResult, TaffyLayout, TaffyResult, TaffyReturnCode,
TaffyStyleMutRef,
bail, bail_if_null, ok, try_or, TaffyFFIDefault, TaffyFFIResult, TaffyLayout, TaffyMeasureMode, TaffyResult,
TaffyReturnCode, TaffySize, TaffyStyleMutRef,
};
use ::core::ffi::c_void;
use taffy::prelude as core;
use taffy::style::AvailableSpace;
use taffy::Taffy as CoreTaffy;

pub type TaffyMeasureFunction = extern "C" fn(
width_measure_mode: TaffyMeasureMode,
width: f32,
height_measure_mode: TaffyMeasureMode,
height: f32,
context: *mut c_void,
) -> TaffySize;

#[allow(dead_code)] // false positive
struct NodeContext {
context: *mut c_void,
measure_function: TaffyMeasureFunction,
}

pub struct TaffyTree {
inner: CoreTaffy,
inner: CoreTaffy<NodeContext>,
}
pub type TaffyTreeOwnedRef = *mut TaffyTree;
pub type TaffyTreeMutRef = *mut TaffyTree;
Expand Down Expand Up @@ -94,7 +110,33 @@ pub unsafe extern "C" fn TaffyTree_ComputeLayout(
width: available_space_from_f32(available_width),
height: available_space_from_f32(available_height),
};
try_or!(InvalidNodeId, tree.inner.compute_layout(node_id.into(), available_space));
try_or!(
InvalidNodeId,
tree.inner.compute_layout_with_measure(
node_id.into(),
available_space,
|known_dimensions, available_space, _node_id, node_context| {
let (width, width_measure_mode) = match (known_dimensions.width, available_space.width) {
(Some(width), _) => (width, TaffyMeasureMode::Exact),
(None, AvailableSpace::Definite(width)) => (width, TaffyMeasureMode::FitContent),
(None, AvailableSpace::MaxContent) => (f32::INFINITY, TaffyMeasureMode::MaxContent),
(None, AvailableSpace::MinContent) => (f32::INFINITY, TaffyMeasureMode::MinContent),
};
let (height, height_measure_mode) = match (known_dimensions.height, available_space.height) {
(Some(height), _) => (height, TaffyMeasureMode::Exact),
(None, AvailableSpace::Definite(height)) => (height, TaffyMeasureMode::FitContent),
(None, AvailableSpace::MaxContent) => (f32::INFINITY, TaffyMeasureMode::MaxContent),
(None, AvailableSpace::MinContent) => (f32::INFINITY, TaffyMeasureMode::MinContent),
};
match node_context {
Some(NodeContext { measure_function, context }) => {
measure_function(width_measure_mode, width, height_measure_mode, height, *context).into()
}
_ => core::Size::ZERO,
}
}
)
);
TaffyReturnCode::Ok
})
}
Expand Down Expand Up @@ -165,6 +207,24 @@ pub unsafe extern "C" fn TaffyTree_GetStyleMut(
})
}

/// Create a new Node in the TaffyTree. Returns a NodeId handle to the node.
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn TaffyTree_SetNodeContext(
raw_tree: TaffyTreeMutRef,
node_id: TaffyNodeId,
measure_function: TaffyMeasureFunction,
context: *mut c_void,
) -> TaffyReturnCode {
with_tree_mut!(raw_tree, tree, {
try_or!(
InvalidNodeId,
tree.inner.set_node_context(node_id.into(), Some(NodeContext { measure_function, context }))
);
ok!(TaffyReturnCode::Ok);
})
}

/// Create a new Node in the TaffyTree. Returns a NodeId handle to the node.
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
Expand Down
29 changes: 29 additions & 0 deletions ctaffy/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ pub enum TaffyUnit {
Fr,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub enum TaffyMeasureMode {
/// A none value (used to unset optional fields)
Exact,
/// Fixed Length (pixel) value
FitContent,
/// Percentage value
MinContent,
/// Min-content size
MaxContent,
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct TaffySize {
width: f32,
height: f32,
}
impl From<TaffySize> for core::Size<f32> {
#[inline(always)]
fn from(value: TaffySize) -> Self {
core::Size {
width: value.width,
height: value.height,
}
}
}

#[repr(C)]
pub struct TaffyLayout {
pub x: f32,
Expand Down

0 comments on commit 2a7cc5a

Please sign in to comment.