task(CAD-5): mline tool (parallel double line with miter offsets + optional end caps) + block editor service (open copies / save back / discard) with block-edit tool

This commit is contained in:
Agent Zero
2026-08-31 00:53:08 +02:00
parent 7331f5fb88
commit 0ffe954559
4 changed files with 595 additions and 2 deletions
@@ -25,6 +25,9 @@ import {
extendElement,
filletElements,
} from '../../../tools/modification/geometry';
import { openBlockForEdit, saveBlockEdit, discardBlockEdit } from '../../../services/blockEditorService';
import { BLOCK_EDIT_MARKER } from '../../../services/blockEditorService';
export { BLOCK_EDIT_MARKER };
import type { Pt } from '../../../tools/modification/geometry';
const uid = (prefix: string): string =>
@@ -1861,6 +1864,57 @@ export const measureTool: ToolExtensionV2 = {
},
};
// ─────────────────────────────────────────────────────────────
// Task CAD-5: Block-Editor — Blockdefinition in-place bearbeiten.
// Klick 1 auf Block-Instanz oeffnet (markierte Kopien erscheinen),
// Kopien normal bearbeiten, Klick 2 speichert zurueck in die
// Definition, cancel verwirft. (Service: blockEditorService)
// ─────────────────────────────────────────────────────────────
export const blockEditTool: ToolExtensionV2 = {
manifest: {
id: 'block-edit',
label: 'Block bearbeiten',
icon: '\u2699',
ribbonTab: 'canvas',
tags: ['pro'],
description: 'Block-Instanz anklicken um die Definition zu bearbeiten (CAD-5)',
},
optionsSchema: [],
handlers: {
down(e, ctx) {
const c = ctx as FullToolContext;
if (!c.doc || !c.selection) return;
// Offene Sitzung? → speichern
if ((c.doc.getAllElements() as CADElement[]).some(
(el) => (el.properties as Record<string, unknown>)[BLOCK_EDIT_MARKER],
)) {
const saved = saveBlockEdit(c.doc as never);
ctx.setStatus(saved ? `Block "${saved}" gespeichert` : 'Speichern fehlgeschlagen');
return;
}
const hit = c.selection.hitTest(e.world.x, e.world.y, 8);
if (!hit || hit.type !== 'block_instance') {
ctx.setStatus('Block bearbeiten: Block-Instanz anklicken');
return;
}
const blockId = (hit.properties as Record<string, unknown>).blockId as string | undefined;
if (!blockId) {
ctx.setStatus('Block bearbeiten: Instanz ohne Block-Referenz');
return;
}
const opened = openBlockForEdit(c.doc as never, blockId);
ctx.setStatus(opened ? `Block "${blockId}" geöffnet — Elemente bearbeiten, erneut klicken speichert` : 'Block konnte nicht geöffnet werden');
},
cancel(ctx) {
const c = ctx as FullToolContext;
if (c.doc) discardBlockEdit(c.doc as never);
ctx.setPreview?.(null);
ctx.setStatus('Block-Bearbeitung verworfen');
},
},
};
export const coreModifyPlugin: PluginV2 = {
manifest: {
id: 'core-modify',
@@ -1871,5 +1925,5 @@ export const coreModifyPlugin: PluginV2 = {
category: 'tools',
enabledByDefault: true,
},
tools: [selectTool, hatchTool, moveTool, copyTool, rotateTool, scaleTool, mirrorTool, deleteTool, offsetTool, trimTool, extendTool, filletTool, arrayRectTool, arrayPolarTool, chamferTool, lengthenTool, joinTool, explodeTool, alignTool, polylineEditTool, stretchTool, breakTool, arrayPathTool, divideTool, measureTool],
tools: [selectTool, hatchTool, moveTool, copyTool, rotateTool, scaleTool, mirrorTool, deleteTool, offsetTool, trimTool, extendTool, filletTool, arrayRectTool, arrayPolarTool, chamferTool, lengthenTool, joinTool, explodeTool, alignTool, polylineEditTool, stretchTool, breakTool, arrayPathTool, divideTool, measureTool, blockEditTool],
};