Files
web-cad/frontend/src/services/commandRegistry.ts
T

154 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* CommandRegistry Zentrale Befehls-Registry für die CAD-Command-Line.
* F-CAD-05: Command Line (L, C, PL, R, A, T, DIM shortcuts)
* F-UI-04: Autovervollständigung
*/
export interface CommandDefinition {
/** Primärer Befehlsname (Großbuchstaben) */
name: string;
/** Aliasse / Kurzformen */
aliases: string[];
/** Tool-ID die aktiviert wird (null für Meta-Befehle wie UNDO) */
toolId: string | null;
/** Beschreibung für Autovervollständigung */
description: string;
/** Kategorie für Gruppierung */
category: 'draw' | 'modify' | 'view' | 'meta' | 'special';
/** Deutsches Label für Command-History-Ausgabe */
label: string;
}
const commands: CommandDefinition[] = [
// ─── Zeichen-Werkzeuge ─────────────────────────────
{ name: 'LINE', aliases: ['L', 'LINIE'], toolId: 'line', description: 'Linie zeichnen', category: 'draw', label: 'Linie-Werkzeug aktiv · Klicken zum Starten' },
{ name: 'CIRCLE', aliases: ['C', 'KREIS'], toolId: 'circle', description: 'Kreis zeichnen', category: 'draw', label: 'Kreis-Werkzeug aktiv · Klicken für Mittelpunkt' },
{ name: 'ARC', aliases: ['A', 'BOGEN'], toolId: 'arc', description: 'Bogen zeichnen', category: 'draw', label: 'Bogen-Werkzeug aktiv · Klicken für Mittelpunkt' },
{ name: 'RECT', aliases: ['R', 'RECTANGLE', 'RECHTECK'], toolId: 'rect', description: 'Rechteck zeichnen', category: 'draw', label: 'Rechteck-Werkzeug aktiv · Klicken für erste Ecke' },
{ name: 'POLYLINE', aliases: ['PL', 'POLYLINIE'], toolId: 'polyline', description: 'Polylinie zeichnen', category: 'draw', label: 'Polylinie-Werkzeug aktiv · Klicken für Punkte, Doppelklick zum Beenden' },
{ name: 'POLYGON', aliases: ['POL', 'POLYGON'], toolId: 'polygon', description: 'Polygon zeichnen', category: 'draw', label: 'Polygon-Werkzeug aktiv · Klicken für Punkte, Doppelklick zum Beenden' },
{ name: 'TEXT', aliases: ['T', 'TXT'], toolId: 'text', description: 'Text platzieren', category: 'draw', label: 'Text-Werkzeug aktiv · Klicken zum Platzieren' },
{ name: 'DIMENSION', aliases: ['DIM', 'BEMASSUNG'], toolId: 'dimension', description: 'Bemaßung erstellen', category: 'draw', label: 'Bemaßung-Werkzeug aktiv · Klicken für Startpunkt' },
{ name: 'LEADER', aliases: ['LD', 'HINWEIS'], toolId: 'leader', description: 'Hinweislinie erstellen', category: 'draw', label: 'Hinweislinie · Klicken für Pfeilspitze, dann für Textposition' },
{ name: 'REVCLOUD', aliases: ['REV', 'REVISIONSWOLKE'], toolId: 'revcloud', description: 'Revisionswolke zeichnen', category: 'draw', label: 'Revisionswolke · Klicken für Punkte, Doppelklick oder Enter zum Beenden' },
{ name: 'HATCH', aliases: ['H', 'SCHRAFFUR'], toolId: 'hatch', description: 'Schraffur erstellen', category: 'draw', label: 'Schraffur-Werkzeug aktiv · Fläche wählen' },
// ─── Änderungs-Werkzeuge ───────────────────────────
{ name: 'MOVE', aliases: ['M', 'VERSCHIEBEN'], toolId: 'move', description: 'Elemente verschieben', category: 'modify', label: 'Verschieben · Elemente auswählen, dann Basispunkt klicken' },
{ name: 'COPY', aliases: ['CO', 'KOPIEREN'], toolId: 'copy', description: 'Elemente kopieren', category: 'modify', label: 'Kopieren · Elemente auswählen, dann Basispunkt klicken' },
{ name: 'ROTATE', aliases: ['RO', 'ROTIEREN'], toolId: 'rotate', description: 'Elemente rotieren', category: 'modify', label: 'Rotieren · Elemente auswählen, dann Basispunkt klicken' },
{ name: 'SCALE', aliases: ['SC', 'SKALIEREN'], toolId: 'scale', description: 'Elemente skalieren', category: 'modify', label: 'Skalieren · Elemente auswählen, dann Basispunkt klicken' },
{ name: 'MIRROR', aliases: ['MI', 'SPIEGELN'], toolId: 'mirror', description: 'Elemente spiegeln', category: 'modify', label: 'Spiegeln · Elemente auswählen, dann Spiegellinie klicken' },
{ name: 'TRIM', aliases: ['TR', 'TRIMMEN'], toolId: 'trim', description: 'Elemente trimmen', category: 'modify', label: 'Trimmen · Begrenzungselement klicken, dann zu trimmendes Element' },
{ name: 'EXTEND', aliases: ['EX', 'VERLANGERN'], toolId: 'extend', description: 'Elemente verlängern', category: 'modify', label: 'Verlängern · Begrenzungselement klicken, dann zu verlängerndes Element' },
{ name: 'FILLET', aliases: ['F', 'ABRUNDEN'], toolId: 'fillet', description: 'Elemente abrunden', category: 'modify', label: 'Abrunden · Erstes Element klicken, dann zweites Element' },
{ name: 'OFFSET', aliases: ['O', 'VERSATZ'], toolId: 'offset', description: 'Versatz erstellen', category: 'modify', label: 'Versatz · Element klicken, dann Richtung und Abstand klicken' },
{ name: 'ERASE', aliases: ['E', 'DEL', 'DELETE', 'LOSCHEN'], toolId: 'delete', description: 'Elemente löschen', category: 'modify', label: 'Löschen · Klicken Sie auf zu löschende Elemente' },
// ─── Ansicht ──────────────────────────────────────
{ name: 'SELECT', aliases: ['V', 'AUSWAHL'], toolId: 'select', description: 'Auswahl-Werkzeug', category: 'view', label: 'Auswahl-Werkzeug aktiv' },
{ name: 'PAN', aliases: ['P'], toolId: 'pan', description: 'Pan-Ansicht', category: 'view', label: 'Pan-Werkzeug aktiv' },
{ name: 'ZOOM', aliases: ['Z'], toolId: 'zoom', description: 'Zoom-Ansicht', category: 'view', label: 'Zoom-Werkzeug aktiv' },
{ name: 'GRID', aliases: ['G', 'GRID'], toolId: null, description: 'Grid ein/aus', category: 'view', label: 'Grid ein/aus' },
{ name: 'ORTHO', aliases: ['OR'], toolId: null, description: 'Ortho-Modus ein/aus', category: 'view', label: 'Ortho-Modus ein/aus' },
{ name: 'SNAP', aliases: ['SN'], toolId: null, description: 'Snap ein/aus', category: 'view', label: 'Snap ein/aus' },
// ─── Meta-Befehle ─────────────────────────────────
{ name: 'UNDO', aliases: ['U'], toolId: null, description: 'Rückgängig', category: 'meta', label: 'Rückgängig: letzte Aktion' },
{ name: 'REDO', aliases: ['RE'], toolId: null, description: 'Wiederherstellen', category: 'meta', label: 'Wiederherstellen: letzte Aktion' },
{ name: 'GROUP', aliases: ['GRP'], toolId: null, description: 'Gruppe erstellen', category: 'meta', label: 'Gruppe erstellt' },
{ name: 'UNGROUP', aliases: ['UNG'], toolId: null, description: 'Gruppe auflösen', category: 'meta', label: 'Gruppe aufgelöst' },
{ name: 'SAVE', aliases: ['S', 'SPEICHERN'], toolId: null, description: 'Projekt speichern', category: 'meta', label: 'Projekt gespeichert' },
{ name: 'NEW', aliases: ['N', 'NEU'], toolId: null, description: 'Neues Projekt', category: 'meta', label: 'Neues Projekt' },
{ name: 'OPEN', aliases: ['OP', 'OFFNEN'], toolId: null, description: 'Projekt öffnen', category: 'meta', label: 'Projekt öffnen' },
{ name: 'IMPORT', aliases: ['IMP', 'I'], toolId: null, description: 'Datei importieren (DXF, SVG, JSON)', category: 'meta', label: 'Datei importieren' },
{ name: 'EXPORT', aliases: ['EXP', 'EX'], toolId: null, description: 'Export als DXF, SVG, PDF, PNG, JSON', category: 'meta', label: 'Export starten' },
// ─── Spezielle Befehle ────────────────────────────
{ name: 'BESTUHLUNG', aliases: ['BEST', 'SEATING'], toolId: null, description: 'Bestuhlung automatisch generieren', category: 'special', label: 'Bestuhlung-Modus' },
{ name: 'BLOCK', aliases: ['B', 'BLOCK'], toolId: null, description: 'Block erstellen', category: 'special', label: 'Block-Erstellung' },
{ name: 'TISCH', aliases: ['TAB', 'TABLE'], toolId: null, description: 'Tisch platzieren', category: 'special', label: 'Tisch-Werkzeug' },
{ name: 'BUHNE', aliases: ['BU', 'STAGE'], toolId: null, description: 'Bühne platzieren', category: 'special', label: 'Bühnen-Werkzeug' },
{ name: 'KI', aliases: ['AI', 'COPilot'], toolId: null, description: 'KI Copilot öffnen', category: 'special', label: 'KI Copilot' },
];
/** Alle Befehle als Map: Schlüssel = NAME + Aliasse (alle Großbuchstaben) */
const commandMap: Map<string, CommandDefinition> = new Map();
for (const cmd of commands) {
commandMap.set(cmd.name, cmd);
for (const alias of cmd.aliases) {
commandMap.set(alias.toUpperCase(), cmd);
}
}
export class CommandRegistry {
/** Alle Befehle zurückgeben */
getAllCommands(): CommandDefinition[] {
return commands;
}
/** Befehl nach Name oder Alias suchen */
lookup(input: string): CommandDefinition | null {
const upper = input.trim().toUpperCase();
return commandMap.get(upper) ?? null;
}
/** Tool-ID für Befehl suchen */
getToolId(input: string): string | null {
const cmd = this.lookup(input);
return cmd?.toolId ?? null;
}
/** Label für Befehl suchen */
getLabel(input: string): string | null {
const cmd = this.lookup(input);
return cmd?.label ?? null;
}
/**
* Autovervollständigung: Sucht Befehle die mit dem Input beginnen.
* Gibt sortierte Liste zurück (max. 10 Einträge).
*/
autocomplete(input: string): CommandDefinition[] {
const upper = input.trim().toUpperCase();
if (upper.length === 0) return [];
const matches = new Map<string, { cmd: CommandDefinition; priority: number }>();
for (const cmd of commands) {
let priority = -1;
if (cmd.name === upper) priority = 0;
else if (cmd.aliases.some(a => a.toUpperCase() === upper)) priority = 1;
else if (cmd.name.startsWith(upper)) priority = 2;
else if (cmd.aliases.some(a => a.toUpperCase().startsWith(upper))) priority = 3;
if (priority >= 0) {
const existing = matches.get(cmd.name);
if (!existing || priority < existing.priority) {
matches.set(cmd.name, { cmd, priority });
}
}
}
return Array.from(matches.values())
.sort((a, b) => a.priority - b.priority || a.cmd.name.localeCompare(b.cmd.name))
.slice(0, 10)
.map(m => m.cmd);
}
/** Alle Befehlsnamen + Aliasse für Autovervollständigung */
getAllNames(): string[] {
const names: string[] = [];
for (const cmd of commands) {
names.push(cmd.name);
names.push(...cmd.aliases);
}
return names.map(n => n.toUpperCase());
}
}
/** Singleton-Instanz */
let registryInstance: CommandRegistry | null = null;
export function getCommandRegistry(): CommandRegistry {
if (!registryInstance) {
registryInstance = new CommandRegistry();
}
return registryInstance;
}