mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-24 10:27:00 -06:00
Merge #1033: M3: a variant switch takes the new variant's resizing unless the instance set its own (@MortenHusted)
This commit is contained in:
@@ -354,6 +354,27 @@ fn carry_overrides(from: &Node, to: &mut Node, what: Carry) {
|
||||
}
|
||||
}
|
||||
|
||||
/// An instance switched from variant `was` to `new`: its resizing (sizing and min / max per axis)
|
||||
/// that is still `was`'s follows `new`; what the instance set itself stays in `own`.
|
||||
fn follow_variant_resizing(own: &mut ChildLayout, was: &ChildLayout, new: &ChildLayout) {
|
||||
if own.sizing_h == was.sizing_h {
|
||||
own.sizing_h = new.sizing_h;
|
||||
}
|
||||
if own.sizing_v == was.sizing_v {
|
||||
own.sizing_v = new.sizing_v;
|
||||
}
|
||||
for (o, w, n) in [
|
||||
(&mut own.min_w, was.min_w, new.min_w),
|
||||
(&mut own.max_w, was.max_w, new.max_w),
|
||||
(&mut own.min_h, was.min_h, new.min_h),
|
||||
(&mut own.max_h, was.max_h, new.max_h),
|
||||
] {
|
||||
if *o == w {
|
||||
*o = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy the values of property group `g` of `from` onto `to`, with the variables bound to them.
|
||||
pub(crate) fn copy_group(from: &Node, to: &mut Node, g: &str) {
|
||||
if from.bound.iter().chain(to.bound.iter()).any(|(k, _)| binding_group(k) == Some(g)) {
|
||||
@@ -799,6 +820,7 @@ fn sync_instance_depth(doc: &mut Document, inst: NodeId, depth: usize, spare: BT
|
||||
if let Some(prev) = root.source.and_then(|p| doc.node(p)).filter(|p| sibling_variants(doc, p.id, component)) {
|
||||
let differs = diff_groups(prev, &comp);
|
||||
root.overrides.retain(|g| g == "name" || !differs.contains(&g.as_str()));
|
||||
follow_variant_resizing(&mut fresh.child_layout, &prev.child_layout, &comp.child_layout);
|
||||
}
|
||||
carry_overrides(&root, &mut fresh, Carry::Root);
|
||||
if let Some(r) = doc.node_mut(inst) {
|
||||
|
||||
@@ -657,6 +657,64 @@ fn switching_variants_keeps_overrides_where_the_variants_agreed() {
|
||||
healthy(&s);
|
||||
}
|
||||
|
||||
/// A "Layout" set: Row (horizontal, hugging, a 40 wide "A") and Stacked (vertical, fixed 300 wide,
|
||||
/// "A" filling it). Returns (set, row, stacked).
|
||||
fn layout_set(s: &mut Session) -> (NodeId, NodeId, NodeId) {
|
||||
let mut variants = Vec::new();
|
||||
for (k, (name, props, child)) in [
|
||||
("Layout=Row", json!({"layout": "horizontal", "gap": 8, "sizingH": "hug", "sizingV": "hug", "fills": []}), json!({})),
|
||||
(
|
||||
"Layout=Stacked",
|
||||
json!({"layout": "vertical", "gap": 8, "sizingH": "fixed", "width": 300, "sizingV": "hug", "fills": []}),
|
||||
json!({"sizingH": "fill"}),
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
let c = idv(&ex(s, "node.create", json!({"type": "component", "name": name, "x": k as f64 * 400.0, "props": props})));
|
||||
ex(s, "node.create", json!({"type": "rectangle", "parent": c, "name": "A", "width": 40, "height": 20, "props": child}));
|
||||
variants.push(c);
|
||||
}
|
||||
let set = idv(&ex(s, "component.combineVariants", json!({"ids": variants.clone()})));
|
||||
(set, variants[0], variants[1])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switching_variants_takes_the_new_variants_resizing_unless_the_instance_set_its_own() {
|
||||
let mut s = Session::new();
|
||||
let (set, row, stacked) = layout_set(&mut s);
|
||||
let i = idv(&ex(&mut s, "instance.create", json!({"component": set, "x": 0, "y": 200})));
|
||||
assert_eq!(component_of(&s, i), row);
|
||||
ex(&mut s, "instance.setProperties", json!({"ids": [i], "properties": {"Layout": "Stacked"}}));
|
||||
assert_eq!(component_of(&s, i), stacked);
|
||||
let direct = idv(&ex(&mut s, "instance.create", json!({"component": stacked, "x": 0, "y": 400})));
|
||||
let (n, d) = (node(&s, i), node(&s, direct));
|
||||
assert_eq!(n.child_layout.sizing_h, Sizing::Fixed, "Row's Hug was never the instance's own: it takes Stacked's Fixed");
|
||||
assert_eq!((n.width, n.child_layout.sizing_h), (d.width, d.child_layout.sizing_h), "the same as an instance made from Stacked");
|
||||
let a = layer(&s, i, "A").unwrap();
|
||||
assert_eq!((node(&s, a).child_layout.sizing_h, node(&s, a).width), (Sizing::Fill, 300.0), "A fills the 300 wide instance");
|
||||
// Filling an auto layout parent afterwards leaves A filling, with nothing turned into an override.
|
||||
let col = idv(&ex(
|
||||
&mut s,
|
||||
"node.create",
|
||||
json!({"type": "frame", "name": "Column", "x": 600, "y": 0, "width": 500, "props": {"layout": "vertical", "sizingH": "fixed", "sizingV": "hug", "fills": []}}),
|
||||
));
|
||||
ex(&mut s, "node.reparent", json!({"ids": [i], "parent": col}));
|
||||
ex(&mut s, "node.set", json!({"ids": [i], "props": {"sizingH": "fill"}}));
|
||||
let a = layer(&s, i, "A").unwrap();
|
||||
assert_eq!(node(&s, a).child_layout.sizing_h, Sizing::Fill, "A still fills");
|
||||
assert!(!node(&s, a).overrides.contains("resizing"), "A's resizing is still the main's");
|
||||
assert_eq!(node(&s, a).width, node(&s, i).width);
|
||||
// Resizing the instance set itself stays across a switch.
|
||||
let own = idv(&ex(&mut s, "instance.create", json!({"component": set, "x": 0, "y": 600})));
|
||||
ex(&mut s, "node.set", json!({"ids": [own], "props": {"minWidth": 120}}));
|
||||
ex(&mut s, "instance.setProperties", json!({"ids": [own], "properties": {"Layout": "Stacked"}}));
|
||||
assert_eq!(node(&s, own).child_layout.min_w, Some(120.0), "its own min width stays");
|
||||
assert_eq!(node(&s, own).child_layout.sizing_h, Sizing::Fixed, "its sizing, still Row's, follows Stacked");
|
||||
healthy(&s);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn variant_combinations_order_default_and_conflicts() {
|
||||
let mut s = Session::new();
|
||||
|
||||
Reference in New Issue
Block a user