diff --git a/crates/ui-egui/src/dialogs/layer_options.rs b/crates/ui-egui/src/dialogs/layer_options.rs index 6b3d29408..beb6321a5 100644 --- a/crates/ui-egui/src/dialogs/layer_options.rs +++ b/crates/ui-egui/src/dialogs/layer_options.rs @@ -53,7 +53,8 @@ pub(super) fn note_set(d: &mut Dialog, field: &str, value: &Value) { } /// Turns Template on or off. A template is locked and dims its images, and turning Template off -/// unlocks it and turns Dim Images off. For several rows, OK sends Lock and Dim Images only when +/// unlocks it and turns Dim Images off; a Lock or Dim Images that was set in the dialog keeps its +/// value. For several rows, OK sends Lock and Dim Images only when /// they are set in the dialog. `layer.setProps` then locks each row that becomes a template and /// dims it to 50%, unless a percentage is set in the dialog, so the dialog shows 50%; it unlocks /// each row that stops being a template and stops dimming it. @@ -61,8 +62,11 @@ pub(super) fn note_set(d: &mut Dialog, field: &str, value: &Value) { /// the dialog show the first row's values again. fn set_template(d: &mut Dialog, on: bool) { choose(d, "template", json!(on)); - d.fields.insert("locked".into(), json!(on)); - d.fields.insert("dimImages".into(), json!(on)); + for key in ["locked", "dimImages"] { + if !is_set(d, key) { + d.fields.insert(key.into(), json!(on)); + } + } let Some(opened) = d.fields.get(OPENED).cloned() else { return; }; @@ -584,6 +588,27 @@ mod tests { assert_eq!(p, json!({"template": false, "dimImages": 40.0, "ids": [first.0, second.0]})); } + /// Lock and Dim Images set in the dialog stay as set when Template is set after them, so + /// `ui.dialog.set` gives the same result in either order. + #[test] + fn template_keeps_lock_and_dim_images_that_were_set() { + let mut app = app(); + let (first, second) = two_layers(&mut app); + set(&mut app, "locked", json!(false)); + set(&mut app, "dimImages", json!(false)); + set(&mut app, "template", json!(true)); + let d = app.ui.dialog.as_ref().unwrap(); + assert!(d.bool("template") && !d.bool("locked") && !d.bool("dimImages")); + let by_template_last = params(d).1; + assert_eq!(by_template_last, json!({"template": true, "locked": false, "dimImages": false, "ids": [first.0, second.0]})); + app.run("ui.layerOptions", json!({"ids": [first.0, second.0]})).unwrap(); + draw(&mut app); + set(&mut app, "template", json!(true)); + set(&mut app, "locked", json!(false)); + set(&mut app, "dimImages", json!(false)); + assert_eq!(params(app.ui.dialog.as_ref().unwrap()).1, by_template_last); + } + #[test] fn new_layer_options_make_a_layer_and_objects_get_name_show_and_lock() { let mut app = app(); diff --git a/docs/mcp.md b/docs/mcp.md index 3f2b9333e..6f3fc3033 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -2608,7 +2608,7 @@ and `layerRows`, the rows highlighted in the panel. - **Dialogs and panel state** (control channel and the app's MCP): `ui.layerOptions {ids?}` and `ui.newLayer {sublayer?}` open Layer Options (dialog `layerOptions`: name, color, template, locked, visible, printable, preview, dimImages, dimPercent; OK is one undo step; `ui.dialog.set` of `template` also sets `locked` and `dimImages`, as the - checkbox does; for several `ids` the dialog shows the first row's settings, and OK sends only the fields set with a + checkbox does, except one that was set before it; for several `ids` the dialog shows the first row's settings, and OK sends only the fields set with a control or `ui.dialog.set`; Cmd/Ctrl+Alt+L runs `ui.newLayer` for a new layer), `ui.layersPanelOptions` opens Panel Options (`layersPanelOptions`: layersOnly, locateSelected, rowSize small|medium|large|other, otherSize, thumbLayers, thumbGroups, thumbObjects), and `ui.layersExpand {ids?, open?}` opens or closes rows as their triangles do (Alt-click: everything inside).