From 69c52f50b5ec42d67c8262ca328bd5600cb33724 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Tue, 21 Mar 2023 03:39:59 +0000 Subject: [PATCH] Add grid placement APIs --- src/ffi/error.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- src/ffi/style.rs | 19 ++++++++++++++++--- src/ffi/value.rs | 22 ++++++++++++++++++++++ src/style/grid.rs | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/ffi/error.rs b/src/ffi/error.rs index 5b26eece7..c5da261c9 100644 --- a/src/ffi/error.rs +++ b/src/ffi/error.rs @@ -1,6 +1,12 @@ //! Return types for C FFI -use super::{StyleValue, StyleValueUnit}; +use super::{StyleValue, StyleValueUnit, GridPlacement}; + +pub (crate) trait TaffyFFIResult { + type Value; + fn from_value(value: Self::Value) -> Self; + fn from_return_code(return_code: ReturnCode) -> Self; +} #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] @@ -35,14 +41,45 @@ pub enum ReturnCode { UnexpectedNegative, } +impl TaffyFFIResult for ReturnCode { + type Value = ReturnCode; + fn from_value(value: Self::Value) -> Self { + value + } + fn from_return_code(return_code: ReturnCode) -> Self { + return_code + } +} + #[repr(C)] pub struct StyleValueResult { pub return_code: ReturnCode, pub value: StyleValue, } -impl From for StyleValueResult { - fn from(return_code: ReturnCode) -> Self { +impl TaffyFFIResult for StyleValueResult { + type Value = StyleValue; + fn from_value(value: Self::Value) -> Self { + Self { return_code: ReturnCode::Ok, value } + } + fn from_return_code(return_code: ReturnCode) -> Self { Self { return_code, value: StyleValue { unit: StyleValueUnit::None, value: 0.0 } } } } + + +#[repr(C)] +pub struct GridPlacementResult { + pub return_code: ReturnCode, + pub value: GridPlacement, +} + +impl TaffyFFIResult for GridPlacementResult { + type Value = GridPlacement; + fn from_value(value: Self::Value) -> Self { + Self { return_code: ReturnCode::Ok, value } + } + fn from_return_code(return_code: ReturnCode) -> Self { + Self { return_code, value: GridPlacement { start: 0, end: 0, span: 0 } } + } +} diff --git a/src/ffi/style.rs b/src/ffi/style.rs index 2cba70194..2936a24a5 100644 --- a/src/ffi/style.rs +++ b/src/ffi/style.rs @@ -4,7 +4,7 @@ use crate::geometry::Rect; use crate::prelude as core; use std::ffi::c_void; -use super::{ReturnCode, StyleValue, StyleValueResult, StyleValueUnit}; +use super::{GridPlacement, ReturnCode, StyleValue, StyleValueResult, StyleValueUnit, GridPlacementResult, TaffyFFIResult}; /// A wrapper around [`core::Style`] which allows the individual style properties to be accessed /// via FFI-friendly getter and setter functions @@ -17,7 +17,7 @@ pub struct Style { macro_rules! assert_style_pointer_is_non_null { ($raw_style_ptr:expr) => {{ if ($raw_style_ptr as *const c_void) == std::ptr::null() { - return ReturnCode::NullStylePointer.into(); + return TaffyFFIResult::from_return_code(ReturnCode::NullStylePointer); } }}; } @@ -34,7 +34,8 @@ macro_rules! get_style { let return_value = $block; Box::leak(style_box); - StyleValueResult { return_code: ReturnCode::Ok, value: return_value.into() } + + TaffyFFIResult::from_value(return_value.into()) }}; } @@ -142,3 +143,15 @@ pub unsafe extern "C" fn Taffy_set_padding_trbl( }; }) } + +/* Grid APIs */ + +/// Get grid item's column placement +pub fn style_get_grid_column(raw_style: *mut c_void) -> GridPlacementResult { + get_style!(raw_style, style, style.grid_column) +} + +/// Set grid item's column placement +pub fn style_set_grid_column(raw_style: *mut c_void, placement: GridPlacement) -> ReturnCode { + with_style_mut!(raw_style, style, style.grid_column = placement.into()) +} diff --git a/src/ffi/value.rs b/src/ffi/value.rs index 16483ecfb..7dd9569d1 100644 --- a/src/ffi/value.rs +++ b/src/ffi/value.rs @@ -96,3 +96,25 @@ impl TryFrom for core::LengthPercentageAuto { } } } + +/// For all fields, zero represents not set +#[derive(Debug, Clone, Copy, PartialEq)] +#[repr(C)] +pub struct GridPlacement { + pub start: i16, + pub end: i16, + pub span: u16, +} + +impl From for core::Line { + fn from(placement: GridPlacement) -> Self { + Self::from_raw_parts(placement.start, placement.span, placement.end) + } +} + +impl From> for GridPlacement { + fn from(placement: core::Line) -> Self { + let (start, span, end) = placement.into_raw_parts(); + Self { start, span, end } + } +} diff --git a/src/style/grid.rs b/src/style/grid.rs index 1053f74ff..a85fd67bd 100644 --- a/src/style/grid.rs +++ b/src/style/grid.rs @@ -161,6 +161,39 @@ impl Line { end: self.end.into_origin_zero_placement(explicit_track_count), } } + + /// Convert raw values of start, span, and end into a [`GridPlacement`]. + /// Zero is not a valid value for any of the values and is thus used to indicate unset + /// Only 2 of the 3 values should be set. If all 3 are set then `span_value` is ignored. + pub (crate) fn from_raw_parts(start: i16, span_value: u16, end: i16) -> Self { + match (start, span_value, end) { + (0, 0, 0) => auto(), + (start, 0, 0) => Line { start: line(start), end: auto() }, + (0, 0, end) => Line { start: auto(), end: line(end) }, + (0, span_value, 0) => span(span_value), + (start, span_value, 0) => Line { start: line(start), end: span(span_value) }, + (0, span_value, end) => Line { start: auto(), end: line(end) }, + (start, _, end) => Line { start: line(start), end: line(end) }, + } + } + + /// Convert raw values of start, span, and end into a [`GridPlacement`]. + /// Zero is not a valid value for any of the values and is thus used to indicate unset + /// Only 2 of the 3 values should be set. If all 3 are set then `span_value` is ignored. + pub (crate) fn into_raw_parts(self) -> (i16, u16, i16) { + use GenericGridPlacement::*; + match (self.start, self.end) { + (Line(start), Line(end)) => (start.as_i16(), 0, end.as_i16()), + (Line(start), Span(span)) => (start.as_i16(), span, 0), + (Line(start), Auto) => (start.as_i16(), 1, 0), + (Span(span), Line(end)) => (0, span, end.as_i16()), + (Span(span), Span(_)) => (0, span, 0), + (Span(span), Auto) => (0, span, 0), + (Auto, Line(end)) => (0, 1, end.as_i16()), + (Auto, Span(span)) => (0, span, 0), + (Auto, Auto) => (0, 1, 0), + } + } } impl Line {