mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Edit Points: turning a shape into a freeform is one undo step
shape.editPoints was a noundo command, so the conversion from a preset to custom geometry was never recorded and Ctrl+Z took back the step before it. It is undoable now (only an actual change records a step), and Edit Points ends when Undo turns the shape back into a preset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
22db9261f9
commit
f4afe6d2df
@@ -131,6 +131,7 @@ app's JSON control channel (`deckcraft --control PORT`).
|
||||
|
||||
| Date | What landed |
|
||||
|---|---|
|
||||
| 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-15 | CLI: .txt and .md export includes table cell text, which it used to skip silently (#814) |
|
||||
| 2026-10-15 | PDF export and rendering: `anchorCtr` centres the drawn text block — right-aligned text no longer ran past the box edge (#736) |
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -3623,3 +3623,35 @@ fn table_column_width_of_a_huge_column_is_ignored() {
|
||||
assert_eq!(table_of(&s, id).cols, vec![100.0, 100.0], "no column changes");
|
||||
}
|
||||
}
|
||||
|
||||
/// 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