mirror of
https://github.com/penpot/penpot.git
synced 2025-05-19 07:56:11 +02:00
✨ Serialization of grid layout data (#6148)
* ✨ Add serializators for grid layout properties * ✨ Extract serializers for wasm api module
This commit is contained in:
parent
7284fb539f
commit
83d41dba6f
9 changed files with 892 additions and 282 deletions
|
@ -142,7 +142,7 @@ Shadow styles are serialized as `u8`:
|
|||
|
||||
## Layout
|
||||
|
||||
### Direction
|
||||
### Flex Direction
|
||||
|
||||
| Value | Field |
|
||||
| ----- | ------------- |
|
||||
|
@ -152,6 +152,14 @@ Shadow styles are serialized as `u8`:
|
|||
| 3 | ColumnReverse |
|
||||
| \_ | error |
|
||||
|
||||
### Grid Direction
|
||||
|
||||
| Value | Field |
|
||||
| ----- | ------------- |
|
||||
| 0 | Row |
|
||||
| 1 | Column |
|
||||
| \_ | error |
|
||||
|
||||
### Align Items
|
||||
|
||||
| Value | Field |
|
||||
|
@ -208,6 +216,28 @@ Shadow styles are serialized as `u8`:
|
|||
| 6 | Stretch |
|
||||
| \_ | error |
|
||||
|
||||
### Align Self
|
||||
|
||||
| Value | Field |
|
||||
| ----- | ------- |
|
||||
| 0 | Auto |
|
||||
| 1 | Start |
|
||||
| 2 | End |
|
||||
| 3 | Center |
|
||||
| 4 | Stretch |
|
||||
| \_ | error |
|
||||
|
||||
### Justify Self
|
||||
|
||||
| Value | Field |
|
||||
| ----- | ------- |
|
||||
| 0 | Auto |
|
||||
| 1 | Start |
|
||||
| 2 | End |
|
||||
| 3 | Center |
|
||||
| 4 | Stretch |
|
||||
| \_ | error |
|
||||
|
||||
### Wrap type
|
||||
|
||||
| Value | Field |
|
||||
|
@ -225,6 +255,18 @@ Shadow styles are serialized as `u8`:
|
|||
| 2 | Auto |
|
||||
| \_ | error |
|
||||
|
||||
### Grid Track Type
|
||||
|
||||
| Value | Field |
|
||||
| ----- | ------- |
|
||||
| 0 | Percent |
|
||||
| 1 | Flex |
|
||||
| 2 | Auto |
|
||||
| 3 | Fixed |
|
||||
| \_ | error |
|
||||
|
||||
|
||||
|
||||
## Font
|
||||
|
||||
### Style
|
||||
|
|
|
@ -636,7 +636,7 @@ pub extern "C" fn set_flex_layout_data(
|
|||
padding_bottom: f32,
|
||||
padding_left: f32,
|
||||
) {
|
||||
let dir = shapes::Direction::from_u8(dir);
|
||||
let dir = shapes::FlexDirection::from_u8(dir);
|
||||
let align_items = shapes::AlignItems::from_u8(align_items);
|
||||
let align_content = shapes::AlignContent::from_u8(align_content);
|
||||
let justify_items = shapes::JustifyItems::from_u8(justify_items);
|
||||
|
@ -714,13 +714,89 @@ pub extern "C" fn set_layout_child_data(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_grid_layout_data() {}
|
||||
pub extern "C" fn set_grid_layout_data(
|
||||
dir: u8,
|
||||
row_gap: f32,
|
||||
column_gap: f32,
|
||||
align_items: u8,
|
||||
align_content: u8,
|
||||
justify_items: u8,
|
||||
justify_content: u8,
|
||||
padding_top: f32,
|
||||
padding_right: f32,
|
||||
padding_bottom: f32,
|
||||
padding_left: f32,
|
||||
) {
|
||||
let dir = shapes::GridDirection::from_u8(dir);
|
||||
let align_items = shapes::AlignItems::from_u8(align_items);
|
||||
let align_content = shapes::AlignContent::from_u8(align_content);
|
||||
let justify_items = shapes::JustifyItems::from_u8(justify_items);
|
||||
let justify_content = shapes::JustifyContent::from_u8(justify_content);
|
||||
|
||||
with_current_shape!(state, |shape: &mut Shape| {
|
||||
shape.set_grid_layout_data(
|
||||
dir,
|
||||
row_gap,
|
||||
column_gap,
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
justify_content,
|
||||
padding_top,
|
||||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn add_grid_track() {}
|
||||
pub extern "C" fn set_grid_columns() {
|
||||
let bytes = mem::bytes();
|
||||
|
||||
let entries: Vec<_> = bytes
|
||||
.chunks(size_of::<shapes::RawGridTrack>())
|
||||
.map(|data| shapes::RawGridTrack::from_bytes(data.try_into().unwrap()))
|
||||
.collect();
|
||||
|
||||
with_current_shape!(state, |shape: &mut Shape| {
|
||||
shape.set_grid_columns(entries);
|
||||
});
|
||||
|
||||
mem::free_bytes();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_grid_cell() {}
|
||||
pub extern "C" fn set_grid_rows() {
|
||||
let bytes = mem::bytes();
|
||||
|
||||
let entries: Vec<_> = bytes
|
||||
.chunks(size_of::<shapes::RawGridTrack>())
|
||||
.map(|data| shapes::RawGridTrack::from_bytes(data.try_into().unwrap()))
|
||||
.collect();
|
||||
|
||||
with_current_shape!(state, |shape: &mut Shape| {
|
||||
shape.set_grid_rows(entries);
|
||||
});
|
||||
|
||||
mem::free_bytes();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_grid_cells() {
|
||||
let bytes = mem::bytes();
|
||||
|
||||
let entries: Vec<_> = bytes
|
||||
.chunks(size_of::<shapes::RawGridCell>())
|
||||
.map(|data| shapes::RawGridCell::from_bytes(data.try_into().unwrap()))
|
||||
.collect();
|
||||
|
||||
with_current_shape!(state, |shape: &mut Shape| {
|
||||
shape.set_grid_cells(entries);
|
||||
});
|
||||
|
||||
mem::free_bytes();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
init_gl!();
|
||||
|
|
|
@ -318,7 +318,7 @@ impl Shape {
|
|||
|
||||
pub fn set_flex_layout_data(
|
||||
&mut self,
|
||||
direction: Direction,
|
||||
direction: FlexDirection,
|
||||
row_gap: f32,
|
||||
column_gap: f32,
|
||||
align_items: AlignItems,
|
||||
|
@ -334,7 +334,6 @@ impl Shape {
|
|||
match &mut self.shape_type {
|
||||
Type::Frame(data) => {
|
||||
let layout_data = LayoutData {
|
||||
direction,
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
|
@ -343,11 +342,12 @@ impl Shape {
|
|||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
row_gap,
|
||||
column_gap,
|
||||
};
|
||||
|
||||
let flex_data = FlexData {
|
||||
row_gap,
|
||||
column_gap,
|
||||
direction,
|
||||
wrap_type,
|
||||
};
|
||||
|
||||
|
@ -357,6 +357,73 @@ impl Shape {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_grid_layout_data(
|
||||
&mut self,
|
||||
direction: GridDirection,
|
||||
row_gap: f32,
|
||||
column_gap: f32,
|
||||
align_items: AlignItems,
|
||||
align_content: AlignContent,
|
||||
justify_items: JustifyItems,
|
||||
justify_content: JustifyContent,
|
||||
padding_top: f32,
|
||||
padding_right: f32,
|
||||
padding_bottom: f32,
|
||||
padding_left: f32,
|
||||
) {
|
||||
match &mut self.shape_type {
|
||||
Type::Frame(data) => {
|
||||
let layout_data = LayoutData {
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
justify_content,
|
||||
padding_top,
|
||||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
row_gap,
|
||||
column_gap,
|
||||
};
|
||||
|
||||
let mut grid_data = GridData::default();
|
||||
grid_data.direction = direction;
|
||||
data.layout = Some(Layout::GridLayout(layout_data, grid_data));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_grid_columns(&mut self, tracks: Vec<RawGridTrack>) {
|
||||
let Type::Frame(frame_data) = &mut self.shape_type else {
|
||||
return;
|
||||
};
|
||||
let Some(Layout::GridLayout(_, grid_data)) = &mut frame_data.layout else {
|
||||
return;
|
||||
};
|
||||
grid_data.columns = tracks.iter().map(GridTrack::from_raw).collect();
|
||||
}
|
||||
|
||||
pub fn set_grid_rows(&mut self, tracks: Vec<RawGridTrack>) {
|
||||
let Type::Frame(frame_data) = &mut self.shape_type else {
|
||||
return;
|
||||
};
|
||||
let Some(Layout::GridLayout(_, grid_data)) = &mut frame_data.layout else {
|
||||
return;
|
||||
};
|
||||
grid_data.rows = tracks.iter().map(GridTrack::from_raw).collect();
|
||||
}
|
||||
|
||||
pub fn set_grid_cells(&mut self, cells: Vec<RawGridCell>) {
|
||||
let Type::Frame(frame_data) = &mut self.shape_type else {
|
||||
return;
|
||||
};
|
||||
let Some(Layout::GridLayout(_, grid_data)) = &mut frame_data.layout else {
|
||||
return;
|
||||
};
|
||||
grid_data.cells = cells.iter().map(GridCell::from_raw).collect();
|
||||
}
|
||||
|
||||
pub fn set_blur(&mut self, blur_type: u8, hidden: bool, value: f32) {
|
||||
self.blur = Blur::new(blur_type, hidden, value);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::utils::uuid_from_u32_quartet;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Layout {
|
||||
|
@ -6,14 +9,14 @@ pub enum Layout {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Direction {
|
||||
pub enum FlexDirection {
|
||||
Row,
|
||||
RowReverse,
|
||||
Column,
|
||||
ColumnReverse,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
impl FlexDirection {
|
||||
pub fn from_u8(value: u8) -> Self {
|
||||
match value {
|
||||
0 => Self::Row,
|
||||
|
@ -25,6 +28,22 @@ impl Direction {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum GridDirection {
|
||||
Row,
|
||||
Column,
|
||||
}
|
||||
|
||||
impl GridDirection {
|
||||
pub fn from_u8(value: u8) -> Self {
|
||||
match value {
|
||||
0 => Self::Row,
|
||||
1 => Self::Column,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum AlignItems {
|
||||
Start,
|
||||
|
@ -132,9 +151,82 @@ impl WrapType {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum GridTrackType {
|
||||
Percent,
|
||||
Flex,
|
||||
Auto,
|
||||
Fixed,
|
||||
}
|
||||
|
||||
impl GridTrackType {
|
||||
pub fn from_u8(value: u8) -> Self {
|
||||
match value {
|
||||
0 => Self::Percent,
|
||||
1 => Self::Flex,
|
||||
2 => Self::Auto,
|
||||
3 => Self::Fixed,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct GridTrack {}
|
||||
pub struct GridTrack {
|
||||
track_type: GridTrackType,
|
||||
value: f32,
|
||||
}
|
||||
|
||||
impl GridTrack {
|
||||
pub fn from_raw(raw: &RawGridTrack) -> Self {
|
||||
Self {
|
||||
track_type: GridTrackType::from_u8(raw.track_type),
|
||||
value: f32::from_le_bytes(raw.value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct GridCell {
|
||||
row: i32,
|
||||
row_span: i32,
|
||||
column: i32,
|
||||
column_span: i32,
|
||||
align_self: Option<AlignSelf>,
|
||||
justify_self: Option<JustifySelf>,
|
||||
shape: Option<Uuid>,
|
||||
}
|
||||
|
||||
impl GridCell {
|
||||
pub fn from_raw(raw: &RawGridCell) -> Self {
|
||||
Self {
|
||||
row: i32::from_le_bytes(raw.row),
|
||||
row_span: i32::from_le_bytes(raw.row_span),
|
||||
column: i32::from_le_bytes(raw.column),
|
||||
column_span: i32::from_le_bytes(raw.column_span),
|
||||
align_self: if raw.has_align_self == 1 {
|
||||
AlignSelf::from_u8(raw.align_self)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
justify_self: if raw.has_justify_self == 1 {
|
||||
JustifySelf::from_u8(raw.justify_self)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
shape: if raw.has_shape_id == 1 {
|
||||
Some(uuid_from_u32_quartet(
|
||||
u32::from_le_bytes(raw.shape_id_a),
|
||||
u32::from_le_bytes(raw.shape_id_b),
|
||||
u32::from_le_bytes(raw.shape_id_c),
|
||||
u32::from_le_bytes(raw.shape_id_d),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||
pub enum Sizing {
|
||||
|
@ -156,7 +248,6 @@ impl Sizing {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LayoutData {
|
||||
pub direction: Direction,
|
||||
pub align_items: AlignItems,
|
||||
pub align_content: AlignContent,
|
||||
pub justify_items: JustifyItems,
|
||||
|
@ -165,33 +256,13 @@ pub struct LayoutData {
|
|||
pub padding_right: f32,
|
||||
pub padding_bottom: f32,
|
||||
pub padding_left: f32,
|
||||
}
|
||||
|
||||
impl LayoutData {
|
||||
pub fn is_reverse(&self) -> bool {
|
||||
match &self.direction {
|
||||
Direction::RowReverse | Direction::ColumnReverse => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_row(&self) -> bool {
|
||||
match &self.direction {
|
||||
Direction::RowReverse | Direction::Row => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn is_column(&self) -> bool {
|
||||
match &self.direction {
|
||||
Direction::ColumnReverse | Direction::Column => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub row_gap: f32,
|
||||
pub column_gap: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum AlignSelf {
|
||||
Auto,
|
||||
Start,
|
||||
End,
|
||||
Center,
|
||||
|
@ -201,10 +272,33 @@ pub enum AlignSelf {
|
|||
impl AlignSelf {
|
||||
pub fn from_u8(value: u8) -> Option<AlignSelf> {
|
||||
match value {
|
||||
0 => Some(Self::Start),
|
||||
1 => Some(Self::End),
|
||||
2 => Some(Self::Center),
|
||||
3 => Some(Self::Stretch),
|
||||
0 => Some(Self::Auto),
|
||||
1 => Some(Self::Start),
|
||||
2 => Some(Self::End),
|
||||
3 => Some(Self::Center),
|
||||
4 => Some(Self::Stretch),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum JustifySelf {
|
||||
Auto,
|
||||
Start,
|
||||
End,
|
||||
Center,
|
||||
Stretch,
|
||||
}
|
||||
|
||||
impl JustifySelf {
|
||||
pub fn from_u8(value: u8) -> Option<JustifySelf> {
|
||||
match value {
|
||||
0 => Some(Self::Auto),
|
||||
1 => Some(Self::Start),
|
||||
2 => Some(Self::End),
|
||||
3 => Some(Self::Center),
|
||||
4 => Some(Self::Stretch),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -212,11 +306,26 @@ impl AlignSelf {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FlexData {
|
||||
pub row_gap: f32,
|
||||
pub column_gap: f32,
|
||||
pub direction: FlexDirection,
|
||||
pub wrap_type: WrapType,
|
||||
}
|
||||
|
||||
impl FlexData {
|
||||
pub fn is_reverse(&self) -> bool {
|
||||
match &self.direction {
|
||||
FlexDirection::RowReverse | FlexDirection::ColumnReverse => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_row(&self) -> bool {
|
||||
match &self.direction {
|
||||
FlexDirection::RowReverse | FlexDirection::Row => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FlexData {
|
||||
pub fn is_wrap(&self) -> bool {
|
||||
match self.wrap_type {
|
||||
|
@ -228,9 +337,78 @@ impl FlexData {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct GridData {
|
||||
pub direction: GridDirection,
|
||||
pub rows: Vec<GridTrack>,
|
||||
pub columns: Vec<GridTrack>,
|
||||
// layout-grid-cells ;; map of id->grid-cell
|
||||
pub cells: Vec<GridCell>,
|
||||
}
|
||||
|
||||
impl GridData {
|
||||
pub fn default() -> Self {
|
||||
Self {
|
||||
direction: GridDirection::Row,
|
||||
rows: vec![],
|
||||
columns: vec![],
|
||||
cells: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct RawGridTrack {
|
||||
track_type: u8,
|
||||
value: [u8; 4],
|
||||
}
|
||||
|
||||
impl RawGridTrack {
|
||||
pub fn from_bytes(bytes: [u8; 5]) -> Self {
|
||||
Self {
|
||||
track_type: bytes[0],
|
||||
value: [bytes[1], bytes[2], bytes[3], bytes[4]],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct RawGridCell {
|
||||
row: [u8; 4],
|
||||
row_span: [u8; 4],
|
||||
column: [u8; 4],
|
||||
column_span: [u8; 4],
|
||||
has_align_self: u8,
|
||||
align_self: u8,
|
||||
has_justify_self: u8,
|
||||
justify_self: u8,
|
||||
has_shape_id: u8,
|
||||
shape_id_a: [u8; 4],
|
||||
shape_id_b: [u8; 4],
|
||||
shape_id_c: [u8; 4],
|
||||
shape_id_d: [u8; 4],
|
||||
}
|
||||
|
||||
impl RawGridCell {
|
||||
pub fn from_bytes(bytes: [u8; 37]) -> Self {
|
||||
Self {
|
||||
row: [bytes[0], bytes[1], bytes[2], bytes[3]],
|
||||
row_span: [bytes[4], bytes[5], bytes[6], bytes[7]],
|
||||
column: [bytes[8], bytes[9], bytes[10], bytes[11]],
|
||||
column_span: [bytes[12], bytes[13], bytes[14], bytes[15]],
|
||||
|
||||
has_align_self: bytes[16],
|
||||
align_self: bytes[17],
|
||||
|
||||
has_justify_self: bytes[18],
|
||||
justify_self: bytes[19],
|
||||
|
||||
has_shape_id: bytes[20],
|
||||
shape_id_a: [bytes[21], bytes[22], bytes[23], bytes[24]],
|
||||
shape_id_b: [bytes[25], bytes[26], bytes[27], bytes[28]],
|
||||
shape_id_c: [bytes[29], bytes[30], bytes[31], bytes[32]],
|
||||
shape_id_d: [bytes[33], bytes[34], bytes[35], bytes[36]],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||
|
|
|
@ -159,6 +159,8 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
continue;
|
||||
};
|
||||
|
||||
let mut reflow_parent = false;
|
||||
|
||||
match &shape.shape_type {
|
||||
Type::Frame(Frame {
|
||||
layout: Some(_), ..
|
||||
|
@ -173,10 +175,17 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
// If this is a fill layout but the parent has not been reflown yet
|
||||
// we wait for the next iteration for reflow
|
||||
skip_reflow = true;
|
||||
reflow_parent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if shape.is_layout_vertical_auto()
|
||||
|| shape.is_layout_horizontal_auto()
|
||||
{
|
||||
reflow_parent = true;
|
||||
}
|
||||
|
||||
if !skip_reflow {
|
||||
layout_reflows.push(id);
|
||||
}
|
||||
|
@ -186,6 +195,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
if let Some(child) = shapes.get(&shape.children[0]) {
|
||||
let child_bounds = bounds.find(&child);
|
||||
bounds.insert(shape.id, child_bounds);
|
||||
reflow_parent = true;
|
||||
}
|
||||
}
|
||||
Type::Group(_) => {
|
||||
|
@ -193,6 +203,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
calculate_group_bounds(shape, shapes, &bounds)
|
||||
{
|
||||
bounds.insert(shape.id, shape_bounds);
|
||||
reflow_parent = true;
|
||||
}
|
||||
}
|
||||
Type::Bool(_) => {
|
||||
|
@ -203,6 +214,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
calculate_group_bounds(shape, shapes, &bounds)
|
||||
{
|
||||
bounds.insert(shape.id, shape_bounds);
|
||||
reflow_parent = true;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -211,7 +223,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
}
|
||||
|
||||
if let Some(parent) = shape.parent_id.and_then(|id| shapes.get(&id)) {
|
||||
if parent.has_layout() || parent.is_group_like() {
|
||||
if reflow_parent && (parent.has_layout() || parent.is_group_like()) {
|
||||
entries.push_back(Modifier::reflow(parent.id));
|
||||
}
|
||||
}
|
||||
|
@ -231,6 +243,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
let Type::Frame(frame_data) = &shape.shape_type else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(Layout::FlexLayout(layout_data, flex_data)) = &frame_data.layout {
|
||||
let mut children = flex_layout::reflow_flex_layout(
|
||||
shape,
|
||||
|
@ -242,11 +255,11 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
entries.append(&mut children);
|
||||
}
|
||||
|
||||
if let Some(Layout::GridLayout(layout_data, grid_data)) = &frame_data.layout {
|
||||
let mut children =
|
||||
grid_layout::reflow_grid_layout(shape, layout_data, grid_data, shapes, &bounds);
|
||||
entries.append(&mut children);
|
||||
}
|
||||
// if let Some(Layout::GridLayout(layout_data, grid_data)) = &frame_data.layout {
|
||||
// let mut children =
|
||||
// grid_layout::reflow_grid_layout(shape, layout_data, grid_data, shapes, &bounds);
|
||||
// entries.append(&mut children);
|
||||
// }
|
||||
reflown.insert(*id);
|
||||
}
|
||||
layout_reflows = Vec::new();
|
||||
|
|
|
@ -67,7 +67,7 @@ impl LayoutAxis {
|
|||
layout_data: &LayoutData,
|
||||
flex_data: &FlexData,
|
||||
) -> Self {
|
||||
if layout_data.is_row() {
|
||||
if flex_data.is_row() {
|
||||
Self {
|
||||
main_size: layout_bounds.width(),
|
||||
across_size: layout_bounds.height(),
|
||||
|
@ -77,8 +77,8 @@ impl LayoutAxis {
|
|||
padding_main_end: layout_data.padding_right,
|
||||
padding_across_start: layout_data.padding_top,
|
||||
padding_across_end: layout_data.padding_bottom,
|
||||
gap_main: flex_data.column_gap,
|
||||
gap_across: flex_data.row_gap,
|
||||
gap_main: layout_data.column_gap,
|
||||
gap_across: layout_data.row_gap,
|
||||
is_auto_main: shape.is_layout_horizontal_auto(),
|
||||
is_auto_across: shape.is_layout_vertical_auto(),
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ impl LayoutAxis {
|
|||
padding_main_end: layout_data.padding_bottom,
|
||||
padding_across_start: layout_data.padding_left,
|
||||
padding_across_end: layout_data.padding_right,
|
||||
gap_main: flex_data.row_gap,
|
||||
gap_across: flex_data.column_gap,
|
||||
gap_main: layout_data.row_gap,
|
||||
gap_across: layout_data.column_gap,
|
||||
is_auto_main: shape.is_layout_vertical_auto(),
|
||||
is_auto_across: shape.is_layout_horizontal_auto(),
|
||||
}
|
||||
|
@ -121,10 +121,10 @@ struct ChildAxis {
|
|||
}
|
||||
|
||||
impl ChildAxis {
|
||||
fn new(child: &Shape, child_bounds: &Bounds, layout_data: &LayoutData) -> Self {
|
||||
fn new(child: &Shape, child_bounds: &Bounds, flex_data: &FlexData) -> Self {
|
||||
let id = child.id;
|
||||
let layout_item = child.layout_item;
|
||||
let mut result = if layout_data.is_row() {
|
||||
let mut result = if flex_data.is_row() {
|
||||
Self {
|
||||
id,
|
||||
main_size: child_bounds.width(),
|
||||
|
@ -176,7 +176,6 @@ fn initialize_tracks(
|
|||
shape: &Shape,
|
||||
layout_bounds: &Bounds,
|
||||
layout_axis: &LayoutAxis,
|
||||
layout_data: &LayoutData,
|
||||
flex_data: &FlexData,
|
||||
shapes: &HashMap<Uuid, Shape>,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
|
@ -186,7 +185,7 @@ fn initialize_tracks(
|
|||
let mut children = shape.children.clone();
|
||||
let mut first = true;
|
||||
|
||||
if !layout_data.is_reverse() {
|
||||
if !flex_data.is_reverse() {
|
||||
children.reverse();
|
||||
}
|
||||
|
||||
|
@ -204,7 +203,7 @@ fn initialize_tracks(
|
|||
.box_bounds(&default_bounds)
|
||||
.unwrap_or(default_bounds);
|
||||
|
||||
let child_axis = ChildAxis::new(child, &child_bounds, layout_data);
|
||||
let child_axis = ChildAxis::new(child, &child_bounds, flex_data);
|
||||
|
||||
let child_main_size = child_axis.margin_main_start
|
||||
+ child_axis.margin_main_end
|
||||
|
@ -466,7 +465,6 @@ fn calculate_track_data(
|
|||
shape,
|
||||
layout_bounds,
|
||||
&layout_axis,
|
||||
layout_data,
|
||||
flex_data,
|
||||
shapes,
|
||||
bounds,
|
||||
|
@ -617,7 +615,7 @@ pub fn reflow_flex_layout(
|
|||
let child_bounds = &child_axis.bounds;
|
||||
let delta_v = Vector::new_points(&child_bounds.nw, &position);
|
||||
|
||||
let (new_width, new_height) = if layout_data.is_row() {
|
||||
let (new_width, new_height) = if flex_data.is_row() {
|
||||
(child_axis.main_size, child_axis.across_size)
|
||||
} else {
|
||||
(child_axis.across_size, child_axis.main_size)
|
||||
|
@ -681,7 +679,7 @@ pub fn reflow_flex_layout(
|
|||
0.0
|
||||
};
|
||||
|
||||
let (scale_width, scale_height) = if layout_data.is_row() {
|
||||
let (scale_width, scale_height) = if flex_data.is_row() {
|
||||
(
|
||||
if layout_axis.is_auto_main {
|
||||
auto_main_size / width
|
||||
|
|
|
@ -1,15 +1,59 @@
|
|||
use crate::math::Bounds;
|
||||
#![allow(dead_code, unused_variables)]
|
||||
use crate::math::{Bounds, Matrix, Point, Vector, VectorExt};
|
||||
use crate::shapes::{GridData, LayoutData, Modifier, Shape};
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub fn reflow_grid_layout(
|
||||
_shape: &Shape,
|
||||
_layout_data: &LayoutData,
|
||||
_grid_data: &GridData,
|
||||
_shapes: &HashMap<Uuid, Shape>,
|
||||
_bounds: &HashMap<Uuid, Bounds>,
|
||||
) -> VecDeque<Modifier> {
|
||||
// TODO
|
||||
VecDeque::new()
|
||||
use super::common::GetBounds;
|
||||
|
||||
const MIN_SIZE: f32 = 0.01;
|
||||
const MAX_SIZE: f32 = f32::INFINITY;
|
||||
|
||||
struct CellData<'a> {
|
||||
shape: &'a Shape,
|
||||
main_size: f32,
|
||||
across_size: f32,
|
||||
}
|
||||
|
||||
fn calculate_cell_data<'a>(
|
||||
shape: &Shape,
|
||||
layout_data: &LayoutData,
|
||||
grid_data: &GridData,
|
||||
shapes: &'a HashMap<Uuid, Shape>,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
) -> Vec<CellData<'a>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn child_position(child_bounds: &Bounds, cell: &CellData) -> Point {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn reflow_grid_layout<'a>(
|
||||
shape: &Shape,
|
||||
layout_data: &LayoutData,
|
||||
grid_data: &GridData,
|
||||
shapes: &'a HashMap<Uuid, Shape>,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
) -> VecDeque<Modifier> {
|
||||
let mut result = VecDeque::new();
|
||||
|
||||
let cells = calculate_cell_data(shape, layout_data, grid_data, shapes, bounds);
|
||||
|
||||
for cell in cells.iter() {
|
||||
let child = cell.shape;
|
||||
let child_bounds = bounds.find(child);
|
||||
let position = child_position(&child_bounds, cell);
|
||||
|
||||
let mut transform = Matrix::default();
|
||||
let delta_v = Vector::new_points(&child_bounds.nw, &position);
|
||||
|
||||
if delta_v.x.abs() > MIN_SIZE || delta_v.y.abs() > MIN_SIZE {
|
||||
transform.post_concat(&Matrix::translate(delta_v));
|
||||
}
|
||||
|
||||
result.push_back(Modifier::transform(child.id, transform));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue