mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Merge pull request #946 from Zetenypapp/fix/edit-points-undo
# Conflicts: # crates/engine/src/tests.rs
This commit is contained in:
@@ -133,6 +133,7 @@ app's JSON control channel (`deckcraft --control PORT`).
|
||||
|---|---|
|
||||
| 2026-10-17 | Opening a file caps absurd effect sizes (glow, soft edges, shadows, reflections, on shapes, text and table text) at what Format Shape allows: a glow of 10^18 pt in a .pptx made rendering ask for 34 GB and abort |
|
||||
| 2026-10-17 | Opening a .deckcraft file whose shapes repeat an id gives the repeats fresh ids (groups, layouts and masters too), so the deck validates and edits by id find one shape |
|
||||
| 2026-10-17 | Edit Points: turning a shape into a freeform is one undo step, so Undo brings the original shape back (it used to stay a freeform) |
|
||||
| 2026-10-15 | PPTX trigger sequences keep separate On Click steps, including paragraph builds; synthetic import/edit/save/reopen and headless show regressions |
|
||||
| 2026-10-16 | Export: PNG with a transparent background — the slide background is left out, only the slide's content is drawn (Export… dialog, File › Export, web download, `file.export`/`file.render` `transparentBackground`, `deckcraft-cli render --transparent`) (#784) |
|
||||
| 2026-10-15 | CLI: .txt and .md export includes table cell text, which it used to skip silently (#814) |
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::{Result, Session};
|
||||
pub fn specs() -> Vec<CommandSpec> {
|
||||
vec![
|
||||
cmd!(
|
||||
noundo "shape.editPoints",
|
||||
"shape.editPoints",
|
||||
"Edit Points",
|
||||
["Shape Format", "Insert Shapes", "Edit Shape"],
|
||||
None,
|
||||
|
||||
@@ -3953,3 +3953,35 @@ fn shape_geometry_commands_limit_size_and_position() {
|
||||
let x = xfrm(&s);
|
||||
assert!(within(&s), "rotated resize stored {x:?}");
|
||||
}
|
||||
|
||||
/// Edit Points turns a preset into a freeform: one undo step, so Undo brings the preset back
|
||||
/// (and leaves Edit Points), Redo the freeform; leaving Edit Points adds no step.
|
||||
#[test]
|
||||
fn edit_points_conversion_is_one_undo_step() {
|
||||
use deckcraft_model::Geom;
|
||||
let mut s = Session::with_new();
|
||||
s.execute("slide.new", &json!({"layout": "blank"})).unwrap();
|
||||
s.execute("shape.insert", &json!({"preset": "star5", "rect": [100, 100, 200, 100]})).unwrap();
|
||||
let preset = |s: &Session| matches!(s.doc().unwrap().selected_shapes()[0].geom, Geom::Preset { .. });
|
||||
s.execute("shape.editPoints", &json!({"on": true})).unwrap();
|
||||
assert!(!preset(&s), "Edit Points made a freeform");
|
||||
assert!(s.tool.editing_points(s.doc().unwrap()).is_some());
|
||||
s.execute("shape.editPoints", &json!({"on": false})).unwrap();
|
||||
// Leaving changed nothing, so the next undo is the conversion itself.
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert!(preset(&s), "Undo brings the star back");
|
||||
s.execute("edit.redo", &json!({})).unwrap();
|
||||
assert!(!preset(&s), "Redo makes it a freeform again");
|
||||
// Undo while still editing points ends Edit Points: the star has no points to edit.
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
s.execute("shape.editPoints", &json!({"on": true})).unwrap();
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert!(preset(&s));
|
||||
assert!(s.tool.editing_points(s.doc().unwrap()).is_none());
|
||||
// A freeform needs no conversion: entering Edit Points again adds no undo step.
|
||||
s.execute("edit.redo", &json!({})).unwrap();
|
||||
s.execute("shape.editPoints", &json!({"on": false})).unwrap();
|
||||
s.execute("shape.editPoints", &json!({"on": true})).unwrap();
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert!(preset(&s), "the only step was the conversion");
|
||||
}
|
||||
|
||||
@@ -280,7 +280,12 @@ impl ToolState {
|
||||
|
||||
/// The shape in Edit Points, while it is still the one selected shape.
|
||||
pub fn editing_points(&self, st: &crate::DocState) -> Option<ShapeId> {
|
||||
self.edit_points.filter(|id| st.selection.shapes.as_slice() == [*id] && st.selection.text.is_none() && st.shape(*id).is_some())
|
||||
// Only a freeform has points: after Undo takes the conversion back, Edit Points is over.
|
||||
self.edit_points.filter(|id| {
|
||||
st.selection.shapes.as_slice() == [*id]
|
||||
&& st.selection.text.is_none()
|
||||
&& st.shape(*id).is_some_and(|sh| matches!(sh.geom, deckcraft_model::Geom::Custom { .. }))
|
||||
})
|
||||
}
|
||||
|
||||
/// A freeform path is being drawn (Enter/Escape/double-click finish it).
|
||||
|
||||
Reference in New Issue
Block a user