feat(508-3a CAD 레이어 합치기 되돌리기): LAYMRG · LAYDEL 뒤 Ctrl+Z 한 번에 도형 레이어 · 레이어 목록 · 현재 층이 함께 돌아오고 Ctrl+Y 도 짝 · 되돌리기 단계에 도면층 전후 담음(state attachLayerChangeToUndo) · vitest layer-tools.test · 요구 325-1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,9 +11,11 @@ import {
|
||||
saveLayerState,
|
||||
} from '../../helpers/layer-history';
|
||||
import {
|
||||
attachLayerChangeToUndo,
|
||||
deleteEntities,
|
||||
getActiveLayerId,
|
||||
getEntities,
|
||||
getLayerSnapshot,
|
||||
getLayers,
|
||||
setActiveLayerId,
|
||||
setLayers,
|
||||
@@ -29,6 +31,13 @@ function updateLayers(mutate: (layers: Layer[]) => Layer[]): void {
|
||||
setLayers(mutate(current.map((layer) => ({ ...layer }))));
|
||||
}
|
||||
|
||||
/** 객체 변경 + 도면층 변경을 되돌리기 한 단계로 묶는다(Ctrl+Z 한 번에 함께 · Ctrl+Y 도 짝) */
|
||||
function withLayerUndo(change: () => void): void {
|
||||
const before = getLayerSnapshot();
|
||||
change();
|
||||
attachLayerChangeToUndo(before, getLayerSnapshot());
|
||||
}
|
||||
|
||||
const layerNameOf = (layerId: string): string =>
|
||||
getLayers().find((layer) => layer.id === layerId)?.name ?? layerId;
|
||||
|
||||
@@ -222,15 +231,17 @@ export const layerMergeToolStateMachine = createSequenceTool({
|
||||
toast.warn('같은 레이어입니다.');
|
||||
return;
|
||||
}
|
||||
// 사본으로 갈아 끼움(제자리 고침 = 되돌리기 칸이 같은 참조 → Ctrl+Z 해도 그대로) · 층 목록 = LAYERP
|
||||
restyle(
|
||||
getEntities().filter((entity) => entity.layerId === sourceId),
|
||||
(entity) => {
|
||||
entity.layerId = targetId;
|
||||
}
|
||||
);
|
||||
updateLayers((layers) => layers.filter((layer) => layer.id !== sourceId));
|
||||
if (getActiveLayerId() === sourceId) setActiveLayerId(targetId);
|
||||
// 사본으로 갈아 끼움(제자리 고침 = 되돌리기 칸이 같은 참조 → Ctrl+Z 해도 그대로)
|
||||
withLayerUndo(() => {
|
||||
restyle(
|
||||
getEntities().filter((entity) => entity.layerId === sourceId),
|
||||
(entity) => {
|
||||
entity.layerId = targetId;
|
||||
}
|
||||
);
|
||||
updateLayers((layers) => layers.filter((layer) => layer.id !== sourceId));
|
||||
if (getActiveLayerId() === sourceId) setActiveLayerId(targetId);
|
||||
});
|
||||
toast.success(`레이어를 ${layerNameOf(targetId)}(으)로 병합했습니다.`);
|
||||
},
|
||||
});
|
||||
@@ -246,9 +257,11 @@ export const layerDeleteToolStateMachine = createSequenceTool({
|
||||
return;
|
||||
}
|
||||
const doomed: Entity[] = getEntities().filter((entity) => entity.layerId === layerId);
|
||||
deleteEntities(doomed, true);
|
||||
updateLayers((layers) => layers.filter((layer) => layer.id !== layerId));
|
||||
if (getActiveLayerId() === layerId) setActiveLayerId(getLayers()[0].id);
|
||||
withLayerUndo(() => {
|
||||
deleteEntities(doomed, true);
|
||||
updateLayers((layers) => layers.filter((layer) => layer.id !== layerId));
|
||||
if (getActiveLayerId() === layerId) setActiveLayerId(getLayers()[0].id);
|
||||
});
|
||||
toast.success(`레이어와 객체 ${doomed.length}개를 삭제했습니다.`);
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user