2D: Text/Textspalte auf Inline-Editing direkt auf der Zeichenfläche umgestellt
Nutzer-Report: Textfelder waren nicht mehrzeilig. Ursache: die Text-/ Textspalte-Werkzeuge holten ihre Eingabe über die Befehlszeile (CommandLine.tsx) — ein einzeiliges <input>, Enter committet sofort, kein Zeilenumbruch möglich. Das betraf auch "Textspalte", obwohl die explizit für mehrzeiligen Wortumbruch gedacht ist. Lösung (Nutzer-Vorgabe: kein Dialog, direktes Editieren auf der Fläche wie im Layout-System): text.ts/textbox.ts committen nach dem Platzieren (Anker bzw. Anker+Breite) sofort ein LEERES Text-Element und melden `focusDrawingId` — dafür CommandResult/EngineHost um einen Passthrough erweitert (engine.ts applyResult ruft host.focusDrawing(id)). App.tsx setzt darauf Auswahl + editTextId (dieselbe State-Variable wie beim bisherigen Doppelklick-Editieren). PlanView rendert bei gesetztem editTextId jetzt einen RichTextEditor-Overlay direkt über dem Element (position:fixed via vbToClient/toScreen, eigene Mini-Toolbar erscheint darüber) statt des bisherigen TextEditorDialog-Modals — Prinzip 1:1 vom Layout-Blatt-Inline- Editor (LayoutSheet.tsx) übernommen. Die neuen Props (editTextId/ onCommitTextEdit/onCloseTextEdit) laufen durch Content/LevelPlanView/ SectionPlanView (viewportContent.tsx) bis zu PlanView durch. Verhalten der beiden Werkzeuge (Nutzer-Vorgabe): "text" bleibt ohne Wortumbruch (kein `width`) — Enter erzeugt weitere Zeilen, aber keine automatische Breite. "textbox" setzt `width` und verhält sich damit wie ein InDesign-Textrahmen (echter Wortumbruch live beim Tippen, kein reines Render-Detail mehr). commitTextEdit (useMouseSelectionHandlers.ts) schreibt jetzt bei JEDEM Tastendruck (kein Guard mehr gegen leeren Text — nötig, damit Löschen bis auf null Zeichen sich sofort spiegelt); neues closeTextEdit räumt ein beim Schliessen noch leeres Element auf (verhindert Leichen bei abgebrochener Neuerstellung). 4 neue Tests (text/textbox: sofortiger Commit + focusDrawingId). tsc -b / vitest run (918/918) / npm run build grün. Rendering/Positionierung des Overlays selbst nicht automatisiert testbar — Nutzer prüft visuell in der Tauri-App.
This commit is contained in:
@@ -22,6 +22,7 @@ import type {
|
||||
} from "../model/types";
|
||||
import { generatePlan, generateSectionPlan } from "../plan/generatePlan";
|
||||
import type { CategoryDisplayResolver } from "../plan/generatePlan";
|
||||
import type { RichTextDoc } from "../text/richText";
|
||||
import { computeSection } from "../plan/toSection";
|
||||
import type { SectionOutput } from "../plan/toSection";
|
||||
import { generateElevationPlan } from "../plan/toElevation";
|
||||
@@ -91,6 +92,9 @@ export function Content({
|
||||
onStampMove,
|
||||
onStampEdit,
|
||||
onEditDrawingText,
|
||||
editTextId,
|
||||
onCommitTextEdit,
|
||||
onCloseTextEdit,
|
||||
onPlanSelect,
|
||||
onPlanMarquee,
|
||||
onSegmentCut,
|
||||
@@ -177,6 +181,9 @@ export function Content({
|
||||
onStampMove: (roomId: string, delta: Vec2) => void;
|
||||
onStampEdit: (roomId: string) => void;
|
||||
onEditDrawingText?: (drawingId: string) => void;
|
||||
editTextId?: string | null;
|
||||
onCommitTextEdit?: (doc: RichTextDoc) => void;
|
||||
onCloseTextEdit?: () => void;
|
||||
onPlanSelect: (sel: PlanSelection) => void;
|
||||
onPlanMarquee: (sel: MarqueeSelection) => void;
|
||||
onSegmentCut: (drawingId: string, model: Vec2) => void;
|
||||
@@ -299,6 +306,9 @@ export function Content({
|
||||
onStampMove={onStampMove}
|
||||
onStampEdit={onStampEdit}
|
||||
onEditDrawingText={onEditDrawingText}
|
||||
editTextId={editTextId}
|
||||
onCommitTextEdit={onCommitTextEdit}
|
||||
onCloseTextEdit={onCloseTextEdit}
|
||||
onOpenSectionLevel={onSelectLevel}
|
||||
onPlanSelect={onPlanSelect}
|
||||
onPlanMarquee={onPlanMarquee}
|
||||
@@ -358,6 +368,9 @@ export function Content({
|
||||
onStampMove={onStampMove}
|
||||
onStampEdit={onStampEdit}
|
||||
onEditDrawingText={onEditDrawingText}
|
||||
editTextId={editTextId}
|
||||
onCommitTextEdit={onCommitTextEdit}
|
||||
onCloseTextEdit={onCloseTextEdit}
|
||||
onOpenSectionLevel={onSelectLevel}
|
||||
onPlanSelect={onPlanSelect}
|
||||
onPlanMarquee={onPlanMarquee}
|
||||
@@ -459,6 +472,9 @@ export function Content({
|
||||
onStampMove={onStampMove}
|
||||
onStampEdit={onStampEdit}
|
||||
onEditDrawingText={onEditDrawingText}
|
||||
editTextId={editTextId}
|
||||
onCommitTextEdit={onCommitTextEdit}
|
||||
onCloseTextEdit={onCloseTextEdit}
|
||||
onOpenSectionLevel={onSelectLevel}
|
||||
onPlanSelect={onPlanSelect}
|
||||
onPlanMarquee={onPlanMarquee}
|
||||
@@ -508,6 +524,9 @@ function LevelPlanView({
|
||||
onStampMove,
|
||||
onStampEdit,
|
||||
onEditDrawingText,
|
||||
editTextId,
|
||||
onCommitTextEdit,
|
||||
onCloseTextEdit,
|
||||
onOpenSectionLevel,
|
||||
onPlanSelect,
|
||||
onPlanMarquee,
|
||||
@@ -550,6 +569,9 @@ function LevelPlanView({
|
||||
onStampMove: (roomId: string, delta: Vec2) => void;
|
||||
onStampEdit: (roomId: string) => void;
|
||||
onEditDrawingText?: (drawingId: string) => void;
|
||||
editTextId?: string | null;
|
||||
onCommitTextEdit?: (doc: RichTextDoc) => void;
|
||||
onCloseTextEdit?: () => void;
|
||||
onOpenSectionLevel?: (id: string) => void;
|
||||
onPlanSelect: (sel: PlanSelection) => void;
|
||||
onPlanMarquee: (sel: MarqueeSelection) => void;
|
||||
@@ -631,6 +653,9 @@ function LevelPlanView({
|
||||
onStampMove={onStampMove}
|
||||
onStampEdit={onStampEdit}
|
||||
onEditDrawingText={onEditDrawingText}
|
||||
editTextId={editTextId}
|
||||
onCommitTextEdit={onCommitTextEdit}
|
||||
onCloseTextEdit={onCloseTextEdit}
|
||||
onOpenSectionLevel={onOpenSectionLevel}
|
||||
onSelect={onPlanSelect}
|
||||
onMarquee={onPlanMarquee}
|
||||
@@ -687,6 +712,9 @@ function SectionPlanView({
|
||||
onStampMove,
|
||||
onStampEdit,
|
||||
onEditDrawingText,
|
||||
editTextId,
|
||||
onCommitTextEdit,
|
||||
onCloseTextEdit,
|
||||
onOpenSectionLevel,
|
||||
onPlanSelect,
|
||||
onPlanMarquee,
|
||||
@@ -724,6 +752,9 @@ function SectionPlanView({
|
||||
onStampMove: (roomId: string, delta: Vec2) => void;
|
||||
onStampEdit: (roomId: string) => void;
|
||||
onEditDrawingText?: (drawingId: string) => void;
|
||||
editTextId?: string | null;
|
||||
onCommitTextEdit?: (doc: RichTextDoc) => void;
|
||||
onCloseTextEdit?: () => void;
|
||||
onOpenSectionLevel?: (id: string) => void;
|
||||
onPlanSelect: (sel: PlanSelection) => void;
|
||||
onPlanMarquee: (sel: MarqueeSelection) => void;
|
||||
@@ -831,6 +862,9 @@ function SectionPlanView({
|
||||
onStampMove={onStampMove}
|
||||
onStampEdit={onStampEdit}
|
||||
onEditDrawingText={onEditDrawingText}
|
||||
editTextId={editTextId}
|
||||
onCommitTextEdit={onCommitTextEdit}
|
||||
onCloseTextEdit={onCloseTextEdit}
|
||||
onOpenSectionLevel={onOpenSectionLevel}
|
||||
onSelect={onPlanSelect}
|
||||
onMarquee={onPlanMarquee}
|
||||
|
||||
Reference in New Issue
Block a user