Allow for fitting paths into a given bounding rectangle

... by applying a transformation. This allows designing a path in some
other path design tool and then make it fit using bindings.
This commit is contained in:
Simon Hausmann 2020-07-13 15:38:56 +02:00
parent 79ba943882
commit 992f990fa8
12 changed files with 162 additions and 36 deletions

View file

@ -929,11 +929,19 @@ fn compute_layout(component: &Rc<Component>) -> Vec<String> {
" auto y = {};",
compile_expression(&path_layout.y_reference, component)
));
res.push(format!(
" auto width = {};",
compile_expression(&path_layout.width_reference, component)
));
res.push(format!(
" auto height = {};",
compile_expression(&path_layout.height_reference, component)
));
res.push(" sixtyfps::PathLayoutData pl { ".into());
res.push(" &path,".to_owned());
res.push(" {items, std::size(items)},".to_owned());
res.push(" x, y".to_owned());
res.push(" x, y, width, height".to_owned());
res.push(" };".to_owned());
res.push(" sixtyfps::solve_path_layout(&pl);".to_owned());
res.push("}".to_owned());

View file

@ -771,6 +771,8 @@ fn compute_layout(component: &Rc<Component>) -> TokenStream {
let x_pos = compile_expression(&*path_layout.x_reference, &component);
let y_pos = compile_expression(&*path_layout.y_reference, &component);
let width = compile_expression(&*path_layout.width_reference, &component);
let height = compile_expression(&*path_layout.width_reference, &component);
layouts.push(quote! {
solve_path_layout(&PathLayoutData {
@ -778,6 +780,8 @@ fn compute_layout(component: &Rc<Component>) -> TokenStream {
elements: &#path,
x: #x_pos,
y: #y_pos,
width: #width,
height: #height,
});
});
}

View file

@ -53,11 +53,15 @@ pub struct PathLayout {
pub elements: Vec<ElementRc>,
pub x_reference: Box<Expression>,
pub y_reference: Box<Expression>,
pub width_reference: Box<Expression>,
pub height_reference: Box<Expression>,
}
impl ExpressionFieldsVisitor for PathLayout {
fn visit_expressions(&mut self, mut visitor: impl FnMut(&mut Expression)) {
visitor(&mut self.x_reference);
visitor(&mut self.y_reference);
visitor(&mut self.width_reference);
visitor(&mut self.height_reference);
}
}

View file

@ -29,17 +29,16 @@ pub fn lower_layouts(component: &Rc<Component>, diag: &mut Diagnostics) {
false
};
let ref_child = child.clone();
let prop_ref = move |name: &'static str| {
Box::new(Expression::PropertyReference(NamedReference {
element: Rc::downgrade(&ref_child),
name: name.into(),
}))
};
let (x_reference, y_reference) = if is_grid_layout || is_path_layout {
(
Box::new(Expression::PropertyReference(NamedReference {
element: Rc::downgrade(&child),
name: "x".into(),
})),
Box::new(Expression::PropertyReference(NamedReference {
element: Rc::downgrade(&child),
name: "y".into(),
})),
)
(prop_ref("x"), prop_ref("y"))
} else {
(Box::new(Expression::Invalid), Box::new(Expression::Invalid))
};
@ -101,6 +100,8 @@ pub fn lower_layouts(component: &Rc<Component>, diag: &mut Diagnostics) {
path: path_elements_expr,
x_reference,
y_reference,
width_reference: prop_ref("width"),
height_reference: prop_ref("height"),
});
continue;
} else {

View file

@ -280,6 +280,8 @@ impl TypeRegister {
let mut path = BuiltinElement::new("Path");
path.properties.insert("x".to_owned(), Type::Float32);
path.properties.insert("y".to_owned(), Type::Float32);
path.properties.insert("width".to_owned(), Type::Float32);
path.properties.insert("height".to_owned(), Type::Float32);
path.properties.insert("fill_color".to_owned(), Type::Color);
path.properties.insert("stroke_color".to_owned(), Type::Color);
path.properties.insert("stroke_width".to_owned(), Type::Float32);
@ -322,6 +324,8 @@ impl TypeRegister {
let mut path_layout = BuiltinElement::new("PathLayout");
path_layout.properties.insert("x".to_owned(), Type::Float32);
path_layout.properties.insert("y".to_owned(), Type::Float32);
path_layout.properties.insert("width".to_owned(), Type::Float32);
path_layout.properties.insert("height".to_owned(), Type::Float32);
path_layout.properties.insert("commands".to_owned(), Type::String);
path_elements.iter().for_each(|elem| {
path_layout