撤销/重做系统
撤销标记、撤销组、嵌套撤销、各类操作的撤销模式。
核心规则
start_undoMark() / end_undoMark() 只负责把多条撤销记录合并为一步;未包裹时每条记录单独成一步,仍可撤销。
Engine.addEntities() / Engine.eraseEntities() 已自带撤销记录,切勿再手动 added_undoMark / erased_undoMark(撤销实现为从块末尾 pop,重复记录会多删一个原有实体)。只有用 Engine.pcanvas.addEntity / currentSpace.erase 等底层 API 才手动补记。不需要撤销时传 { recordUndo: false }:Engine.addEntities(ents, { recordUndo: false })、Engine.eraseEntities(ents, { recordUndo: false })。
基本用法
const { Engine } = vjcad;
const undoMgr = Engine.undoManager;
// 字符串简写(最常用)
undoMgr.start_undoMark('绘制图形');
try {
// ... 创建/修改/删除实体 ...
Engine.addEntities(entity); // 自带撤销记录,无需再 added_undoMark
} finally {
undoMgr.end_undoMark();
}
嵌套撤销(推荐在命令中使用)
const { Engine } = vjcad;
Engine.startUndoRecord('我的操作'); // 支持嵌套,只有最外层生效
// ... 操作 ...
Engine.endUndoRecord();
新增实体的撤销
undoMgr.start_undoMark('添加实体');
try {
const line = new LineEnt([0, 0], [100, 0]);
line.setDefaults();
Engine.addEntities(line); // 已自动记录撤销
} finally {
undoMgr.end_undoMark();
}
注意:Engine.addEntities() 会自动记录撤销,不要再手动调用 added_undoMark(双重记录会让 Ctrl+Z 多删一个原有实体、重做时新实体被压入两次)。只有用 Engine.pcanvas.addEntity(ent) 底层入库时才需要手动补记:
Engine.pcanvas.addEntity(line); // 底层 API,不记撤销
undoMgr.added_undoMark([line]); // 手动补记
修改已有实体的撤销
undoMgr.start_undoMark('修改颜色');
try {
Engine.markModified(entity); // 先标记(记录修改前状态)
entity.color = 1; // 再修改属性
entity.layer = "新图层";
entity.setModified(); // 通知修改完成
} finally {
undoMgr.end_undoMark();
}
删除实体的撤销
undoMgr.start_undoMark('删除实体');
try {
Engine.eraseEntities(entities); // 自带 erased_undoMark,勿重复记录
} finally {
undoMgr.end_undoMark();
}
变换操作的撤销
const { Point2D } = vjcad;
undoMgr.start_undoMark('移动');
try {
const from = new Point2D(0, 0);
const to = new Point2D(50, 0);
entities.forEach(ent => ent.move(from, to));
undoMgr.moved_undoMark(entities, from, to);
Engine.regen();
} finally {
undoMgr.end_undoMark();
}
其他变换撤销标记:
undoMgr.rotate_undoMark(entities, basePoint, angle);
undoMgr.scaled_undoMark(entities, basePoint, scale);
undoMgr.mirrored_undoMark(entities, p1, p2);
撤销/重做操作
undoMgr.undo(); // 撤销一步
undoMgr.redo(); // 重做一步
undoMgr.undoSteps(3); // 撤销 3 步
undoMgr.undoSteps('绘制图形'); // 按名称撤销到最近匹配项
undoMgr.redoSteps('绘制图形'); // 按名称重做
undoMgr.undoSteps(3, { silent: true }); // 静默撤销(不触发消息)
检查状态
if (undoMgr.canUndo()) { undoMgr.undo(); }
if (undoMgr.canRedo()) { undoMgr.redo(); }
Engine.isInUndoRecord(); // 是否在撤销记录中