154 lines
10 KiB
TypeScript
154 lines
10 KiB
TypeScript
/**
|
||
* 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;
|
||
}
|