task(A4.8): migrate delete/offset tools to v2

This commit is contained in:
Agent Zero
2026-08-27 01:09:51 +02:00
parent 7565016200
commit cf67635732
2 changed files with 174 additions and 3 deletions
@@ -20,6 +20,7 @@ import {
mirrorElement,
angleBetween,
distance,
offsetElement,
} from '../../../tools/modification/geometry';
import type { Pt } from '../../../tools/modification/geometry';
@@ -273,16 +274,106 @@ export const rotateTool: ToolExtensionV2 = makeTransformTool('rotate');
export const scaleTool: ToolExtensionV2 = makeTransformTool('scale');
export const mirrorTool: ToolExtensionV2 = makeTransformTool('mirror');
// ─────────────────────────────────────────────────────────────
// Delete (Task A4.8) — Portierung aus Legacy handleDeleteDown:
// Einzelnklick auf Element löscht es sofort (kein up/Bestätigung).
// Jetzt via doc.deleteElements → undo-fähig.
// ─────────────────────────────────────────────────────────────
export const deleteTool: ToolExtensionV2 = {
manifest: {
id: 'delete', label: 'Löschen', icon: '\u2715', ribbonTab: 'canvas', tags: ['basic'],
description: 'Element anklicken zum Löschen',
},
optionsSchema: [],
handlers: {
down(e, ctx) {
const c = ctx as FullToolContext;
if (!c.doc || !c.selection) return;
const ids = c.selection.getIds();
if (ids.length > 0) {
// Selektion vorhanden → alles selektierte löschen
c.doc.deleteElements(ids);
c.selection.setIds([]);
ctx.setStatus(`${ids.length} Element(e) gelöscht`);
return;
}
// Sonst: direkter Klick-Treffer
const hit = c.selection.hitTest(e.world.x, e.world.y, 5);
if (!hit) return;
c.doc.deleteElements([hit.id]);
ctx.setStatus(`Gelöscht: ${hit.id}`);
},
},
};
// ─────────────────────────────────────────────────────────────
// Offset (Task A4.8) — nutzt die BUG-3-reparierte offsetElement-
// Signatur mit Seitenparameter; Legacy-Ablauf:
// Klick1 = Element wählen, Klick2 = Richtung+Distanz → NEUES Element.
// ─────────────────────────────────────────────────────────────
let offsetSource: CADElement | null = null;
let offsetBase: Pt | null = null;
export const offsetTool: ToolExtensionV2 = {
manifest: {
id: 'offset', label: 'Versatz', icon: '\u2937', ribbonTab: 'canvas', tags: ['pro'],
description: 'Element anklicken, dann seitlichen Versatz klicken',
},
optionsSchema: [],
handlers: {
down(e, ctx) {
const c = ctx as FullToolContext;
if (!c.doc || !c.selection) return;
if (!offsetSource) {
const hit = c.selection.hitTest(e.world.x, e.world.y, 5);
if (!hit) return;
offsetSource = hit;
offsetBase = e.world;
ctx.setStatus(`Offset: Element ${hit.id} gewählt Versatz klicken`);
return;
}
// Zweiter Klick: Distanz + Seite (Kreuzprodukt für Linien, Radius sonst)
const src = c.doc.getElement(offsetSource.id);
if (!src) { offsetSource = null; offsetBase = null; return; }
const dist = Math.hypot(e.world.x - offsetBase!.x, e.world.y - offsetBase!.y);
let side: 1 | -1 = 1;
if (src.type === 'line' && src.properties.x1 !== undefined && src.properties.y1 !== undefined) {
const p1x = src.properties.x1 as number;
const p1y = src.properties.y1 as number;
const p2x = src.properties.x2 as number;
const p2y = src.properties.y2 as number;
side = (p2x - p1x) * (e.world.y - p1y) - (p2y - p1y) * (e.world.x - p1x) >= 0 ? 1 : -1;
} else if ((src.type === 'circle' || src.type === 'arc') && src.properties.radius !== undefined) {
side = Math.hypot(e.world.x - src.x, e.world.y - src.y) >= (src.properties.radius as number) ? 1 : -1;
}
const next = offsetElement(src, dist, side);
let newEl: CADElement | null = null;
c.doc.transact(() => {
newEl = { ...next, id: uid('off') };
c.doc!.addElement(newEl!);
});
ctx.setStatus(`Offset erstellt (${(newEl as unknown as CADElement).id})`);
offsetSource = null;
offsetBase = null;
},
cancel(ctx) {
offsetSource = null;
offsetBase = null;
ctx.setStatus('Offset abgebrochen');
},
},
};
/** V2-Plugin: Kern-Bearbeitungswerkzeuge. */
export const coreModifyPlugin: PluginV2 = {
manifest: {
id: 'core-modify',
name: 'Bearbeiten (Kern)',
version: '1.3.0',
version: '1.4.0',
author: 'web-cad team',
description: 'Auswahl, Schraffur, Verschieben, Kopieren, Rotieren, Skalieren, Spiegeln (V2).',
description: 'Auswahl, Schraffur, Verschieben, Kopieren, Rotieren, Skalieren, Spiegeln, Löschen, Versatz (V2).',
category: 'tools',
enabledByDefault: true,
},
tools: [selectTool, hatchTool, moveTool, copyTool, rotateTool, scaleTool, mirrorTool],
tools: [selectTool, hatchTool, moveTool, copyTool, rotateTool, scaleTool, mirrorTool, deleteTool, offsetTool],
};