mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-31 22:06:49 -06:00
Merge pull request #1458 from MortenHusted/fix/layout-key-order
M2: auto layout settings in one call don't depend on how their keys are spelled
This commit is contained in:
@@ -387,20 +387,34 @@ fn paint_none(v: &Value) -> bool {
|
||||
v.is_null() || v.as_str().is_some_and(|s| s.eq_ignore_ascii_case("none"))
|
||||
}
|
||||
|
||||
/// The order [`apply`] takes keys in: geometry first so rotation applies to the final size, style
|
||||
/// links after the values so a link wins over values its style sets, variable bindings last so
|
||||
/// paints set in the same call don't detach them.
|
||||
/// The order [`apply`] takes keys in: geometry first so rotation applies to the final size, the
|
||||
/// auto layout mode before the keys that tune it (an object `layout` replaces the whole auto
|
||||
/// layout), style links after the values so a link wins over values its style sets, variable
|
||||
/// bindings last so paints set in the same call don't detach them.
|
||||
fn apply_order(k: &str) -> u8 {
|
||||
match k {
|
||||
"path" | "width" | "height" | "w" | "h" => 0,
|
||||
"rotation" => 2,
|
||||
"x" | "y" => 3,
|
||||
"fillStyle" | "strokeStyle" | "effectStyle" | "textStyle" | "gridStyle" => 4,
|
||||
"boundVariables" => 5,
|
||||
_ => 1,
|
||||
"layout" | "layoutMode" => 1,
|
||||
"rotation" => 3,
|
||||
"x" | "y" => 4,
|
||||
"fillStyle" | "strokeStyle" | "effectStyle" | "textStyle" | "gridStyle" => 5,
|
||||
"boundVariables" => 6,
|
||||
_ => 2,
|
||||
}
|
||||
}
|
||||
|
||||
/// Auto layout keys given beside a `layout` (or `layoutMode`) that turns auto layout off: they
|
||||
/// would turn it back on (`layout_mut`), so the call is refused rather than one of them losing.
|
||||
fn layout_keys_beside_none(cmd: &str, props: &Map<String, Value>) -> Result<()> {
|
||||
let off = ["layout", "layoutMode"]
|
||||
.into_iter()
|
||||
.find(|k| props.get(*k).is_some_and(|v| v.is_null() || v.as_str().is_some_and(|s| s.eq_ignore_ascii_case("none"))));
|
||||
let tuning: Vec<String> = props.keys().filter(|k| LAYOUT_KEYS.contains(&k.as_str())).map(|k| format!("`{k}`")).collect();
|
||||
let Some(off) = off.filter(|_| !tuning.is_empty()) else { return Ok(()) };
|
||||
let (what, are) = if tuning.len() == 1 { ("an auto layout property", "is") } else { ("auto layout properties", "are") };
|
||||
Err(bad(cmd, format!("{} {are} {what}, and `{off}` in the same call turns auto layout off", tuning.join(", "))))
|
||||
}
|
||||
|
||||
/// An explicit width (`is_w`) or height makes hugging or filling on that axis fixed, like typing
|
||||
/// into W or H.
|
||||
fn fix_axis(doc: &mut Document, id: NodeId, is_w: bool) -> Result<()> {
|
||||
@@ -995,6 +1009,7 @@ fn apply_shape(cmd: &str, doc: &mut Document, id: NodeId, k: &str, v: &Value) ->
|
||||
|
||||
/// Apply a property map to one node. `x`/`y` are relative to the parent.
|
||||
pub fn apply(cmd: &str, doc: &mut Document, id: NodeId, props: &Map<String, Value>) -> Result<()> {
|
||||
layout_keys_beside_none(cmd, props)?;
|
||||
let mut unknown = Vec::new();
|
||||
let mut keys: Vec<(&String, &Value)> = props.iter().collect();
|
||||
keys.sort_by_key(|(k, _)| apply_order(k));
|
||||
|
||||
Reference in New Issue
Block a user