mirror of
https://github.com/penpot/penpot.git
synced 2025-07-17 00:05:18 +02:00
✨ Improvements on flex layout positioning
This commit is contained in:
parent
4c12af957c
commit
a830c27ceb
6 changed files with 175 additions and 72 deletions
|
@ -1,5 +1,4 @@
|
|||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
mod common;
|
||||
mod constraints;
|
||||
mod flex_layout;
|
||||
|
@ -9,7 +8,7 @@ use uuid::Uuid;
|
|||
|
||||
use common::GetBounds;
|
||||
|
||||
use crate::math::{Bounds, Matrix, Point};
|
||||
use crate::math::{identitish, Bounds, Matrix, Point};
|
||||
use crate::shapes::{
|
||||
ConstraintH, ConstraintV, Frame, Group, Layout, Modifier, Shape, TransformEntry, Type,
|
||||
};
|
||||
|
@ -23,7 +22,7 @@ fn propagate_children(
|
|||
transform: Matrix,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
) -> VecDeque<Modifier> {
|
||||
if shape.children.len() == 0 {
|
||||
if shape.children.len() == 0 || identitish(transform) {
|
||||
return VecDeque::new();
|
||||
}
|
||||
|
||||
|
@ -39,7 +38,13 @@ fn propagate_children(
|
|||
let constraint_h = match &shape.shape_type {
|
||||
Type::Frame(Frame {
|
||||
layout: Some(_), ..
|
||||
}) => ConstraintH::Left,
|
||||
}) => {
|
||||
if child.is_absolute() {
|
||||
child.constraint_h(ConstraintH::Left)
|
||||
} else {
|
||||
ConstraintH::Left
|
||||
}
|
||||
}
|
||||
Type::Frame(_) => child.constraint_h(ConstraintH::Left),
|
||||
_ => child.constraint_h(ConstraintH::Scale),
|
||||
};
|
||||
|
@ -47,7 +52,13 @@ fn propagate_children(
|
|||
let constraint_v = match &shape.shape_type {
|
||||
Type::Frame(Frame {
|
||||
layout: Some(_), ..
|
||||
}) => ConstraintV::Top,
|
||||
}) => {
|
||||
if child.is_absolute() {
|
||||
child.constraint_v(ConstraintV::Top)
|
||||
} else {
|
||||
ConstraintV::Top
|
||||
}
|
||||
}
|
||||
Type::Frame(_) => child.constraint_v(ConstraintV::Top),
|
||||
_ => child.constraint_v(ConstraintV::Scale),
|
||||
};
|
||||
|
@ -108,7 +119,6 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
while let Some(modifier) = entries.pop_front() {
|
||||
match modifier {
|
||||
Modifier::Transform(entry) => {
|
||||
// println!("Transform {}", entry.id);
|
||||
let Some(shape) = state.shapes.get(&entry.id) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -154,8 +164,22 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
layout: Some(_), ..
|
||||
}) => {
|
||||
if !reflown.contains(&id) {
|
||||
layout_reflows.push(id);
|
||||
reflown.insert(id);
|
||||
let mut skip_reflow = false;
|
||||
if shape.is_layout_horizontal_fill()
|
||||
|| shape.is_layout_vertical_fill()
|
||||
{
|
||||
if let Some(parent_id) = shape.parent_id {
|
||||
if !reflown.contains(&parent_id) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !skip_reflow {
|
||||
layout_reflows.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
Type::Group(Group { masked: true }) => {
|
||||
|
@ -196,6 +220,10 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
}
|
||||
|
||||
for id in layout_reflows.iter() {
|
||||
if reflown.contains(&id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(shape) = state.shapes.get(&id) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -203,10 +231,14 @@ 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, layout_data, flex_data, shapes, &bounds);
|
||||
let mut children = flex_layout::reflow_flex_layout(
|
||||
shape,
|
||||
layout_data,
|
||||
flex_data,
|
||||
shapes,
|
||||
&mut bounds,
|
||||
);
|
||||
entries.append(&mut children);
|
||||
}
|
||||
|
||||
|
@ -215,6 +247,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
|||
grid_layout::reflow_grid_layout(shape, layout_data, grid_data, shapes, &bounds);
|
||||
entries.append(&mut children);
|
||||
}
|
||||
reflown.insert(*id);
|
||||
}
|
||||
layout_reflows = Vec::new();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue