mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-14 19:27:07 -04:00
Layers: the active layer falls back to the top layer when it is removed
The active layer lives on DocState, outside the undo snapshots, and nothing re-checked it when the document's layers changed. After New Layer → Undo (or Delete Layer / Delete Unused Layers / Merge Layers on the active layer) it kept pointing at a layer that no longer exists, and every object created next (frames, lines, placed images, pasted items) was put on that phantom layer: not drawn on the canvas, missing from PDF export, ItemLayer referencing an undefined layer in IDML, and preflight reported nothing. After each command, if the active layer is gone, make the top layer active (as on opening a document). Test: active_layer_survives_undoing_new_layer. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
01753f90f3
commit
eee64ae7c9
2 files changed
+31
No files matched your search
@@ -345,6 +345,13 @@ impl Session {
|
||||
(spec.enabled)(self).map_err(|e| EngineError::Disabled(id.into(), e))?;
|
||||
let before = self.active().map(|d| (d.uid, d.doc.clone()));
|
||||
let r = (spec.run)(self, params)?;
|
||||
// Undo, redo or deleting layers can take the active layer away: new objects would land on
|
||||
// a layer that isn't there (invisible, not exported). Fall back to the top layer.
|
||||
if let Some(st) = self.active_mut()
|
||||
&& st.doc.layer(st.active_layer).is_none()
|
||||
{
|
||||
st.active_layer = st.doc.default_layer();
|
||||
}
|
||||
self.record_transform(id, params);
|
||||
if self.prefs.smart_text_reflow && spec.undoable {
|
||||
self.smart_reflow();
|
||||
|
||||
@@ -254,6 +254,30 @@ fn serialized_document_opens_again() {
|
||||
assert_eq!(d["stories"][0]["preview"], "Saved on the web");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_layer_survives_undoing_new_layer() {
|
||||
let mut s = session();
|
||||
let layer_of = |s: &mut Session, id: u64| {
|
||||
let d = s.execute("document.inspect", &json!({})).unwrap();
|
||||
let items = d["spreads"].as_array().unwrap().iter().flat_map(|sp| sp["items"].as_array().unwrap().clone()).collect::<Vec<_>>();
|
||||
let it = items.into_iter().find(|i| i["id"] == id).unwrap();
|
||||
let layers: Vec<Value> = d["layers"].as_array().unwrap().iter().map(|l| l["id"].clone()).collect();
|
||||
(it["layer"].clone(), layers)
|
||||
};
|
||||
// New Layer, then Undo: the new layer is gone, so it can't stay the active one.
|
||||
s.execute("layer.new", &json!({})).unwrap();
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
let f = s.execute("frame.create", &json!({"rect": [36, 36, 300, 200], "content": "text", "text": "Visible"})).unwrap();
|
||||
let (layer, layers) = layer_of(&mut s, f["id"].as_u64().unwrap());
|
||||
assert!(layers.contains(&layer), "frame on layer {layer} not in {layers:?}");
|
||||
// Delete Unused Layers removing the (empty) active layer.
|
||||
s.execute("layer.new", &json!({})).unwrap();
|
||||
s.execute("layer.deleteUnused", &json!({})).unwrap();
|
||||
let f = s.execute("frame.create", &json!({"rect": [36, 236, 300, 400], "content": "text", "text": "Also visible"})).unwrap();
|
||||
let (layer, layers) = layer_of(&mut s, f["id"].as_u64().unwrap());
|
||||
assert!(layers.contains(&layer), "frame on layer {layer} not in {layers:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn step_and_repeat_grid() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in new issue
Block a user