Skip to content

Commit

Permalink
Add grid placement APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed Mar 21, 2023
1 parent 57b7f9f commit 76361cc
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 6 deletions.
43 changes: 40 additions & 3 deletions src/ffi/error.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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<ReturnCode> 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 } }
}
}
19 changes: 16 additions & 3 deletions src/ffi/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}};
}
Expand All @@ -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())
}};
}

Expand Down Expand Up @@ -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())
}
22 changes: 22 additions & 0 deletions src/ffi/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,25 @@ impl TryFrom<StyleValue> 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<GridPlacement> for core::Line<core::GridPlacement> {
fn from(placement: GridPlacement) -> Self {
Self::from_raw_parts(placement.start, placement.span, placement.end)
}
}

impl From<core::Line<core::GridPlacement>> for GridPlacement {
fn from(placement: core::Line<core::GridPlacement>) -> Self {
let (start, span, end) = placement.into_raw_parts();
Self { start, span, end }
}
}
33 changes: 33 additions & 0 deletions src/style/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,39 @@ impl Line<GridPlacement> {
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<OriginZeroGridPlacement> {
Expand Down

0 comments on commit 76361cc

Please sign in to comment.