Inhaltsverzeichnis
TUI Layout
Anchoring-First Responsive Layout für TUI-Anwendungen.
Anchoring ist der Default-Modus - jedes Control verhält sich korrekt bei Terminal-Resize ohne spezielle Container.
Grundprinzip
Anchoring-First bedeutet: - Terminal Resize darf Layout, Focus und Rendering nicht brechen - Controls behalten stabile räumliche Beziehungen - Vorhersagbare Expansion/Shrinking-Regeln
Anchor-Semantik
Verfügbare Anchors
| Anchor | Bedeutung |
| Left | Abstand zum linken Rand bleibt konstant |
|---|---|
| Top | Abstand zum oberen Rand bleibt konstant |
| Right | Abstand zum rechten Rand bleibt konstant |
| Bottom | Abstand zum unteren Rand bleibt konstant |
Kombinationen
Default: Left + Top → Position bleibt stabil, Größe konstant Left + Right: → Breite dehnt/schrumpft mit Parent-Breite Top + Bottom: → Höhe dehnt/schrumpft mit Parent-Höhe Alle vier (Left + Top + Right + Bottom): → Rect dehnt sich in beide Richtungen Keine Anchors: → Behandeln wie Left + Top (keine "floating" Ambiguität)
PXAML Beispiele
<!-- Feste Position oben links --> <Button Anchors="Left,Top" Text="OK" /> <!-- Volle Breite, feste Höhe --> <TextEdit Anchors="Left,Top,Right" Height="3" /> <!-- Füllt gesamten verfügbaren Bereich --> <ListView Anchors="Left,Top,Right,Bottom" /> <!-- Statusleiste unten --> <StatusBar Anchors="Left,Right,Bottom" Height="1" />
Resize-Verhalten
Ablauf bei Resize
1. Resize Event empfangen └─ Root Available Rect aktualisieren 2. Layout invalidieren └─ Measure/Arrange Pass durchführen 3. Focus erhalten └─ Gleicher logischer Control behält Focus 4. Neu rendern └─ Paint → DiffFlush
Deterministisch
PFLICHT: - Gleicher Input → Gleiches Layout - Kein Flicker bei schnellem Resize - Kein Cursor-Corruption - Focus bleibt auf logischem Control
Breakpoints
Optionale aber empfohlene Resize-Schwellwerte:
Standard-Breakpoints
| Breakpoint | Breite | Typisches Layout |
| Narrow | < 80 | Single-Column, gestapelt |
|---|---|---|
| Medium | 80-119 | Sidebar collapsed zu Tabs |
| Wide | >= 120 | Sidebar + Content nebeneinander |
PXAML Konfiguration
<Panel ResponsiveMode="Auto" Breakpoints="80,120"> <!-- Automatisches Reflow bei Breakpoint-Überschreitung --> </Panel>
Breakpoint-Regeln
PFLICHT: - Breakpoints NICHT "magic" - in PXAML oder Theme Config definieren - Breakpoints dokumentieren - Verhalten bei jedem Breakpoint klar definieren
Layout-Container
Stack
Orientierung: Vertikal oder Horizontal Kinder werden nacheinander angeordnet
<Stack Orientation="Vertical"> <Label Text="Name:" /> <TextEdit /> <Label Text="Email:" /> <TextEdit /> </Stack>
Dock
Positionen: Left, Top, Right, Bottom, Fill Kinder docken an Seiten, Rest füllt Mitte
<Dock> <MenuBar Dock="Top" /> <StatusBar Dock="Bottom" /> <Sidebar Dock="Left" Width="20" /> <Content Dock="Fill" /> </Dock>
Overlay
Für Popups, Modals, Tooltips Überlagert andere Controls Muss innerhalb Screen Bounds bleiben (clamped)
<Overlay> <Dialog X="10" Y="5" Width="40" Height="10"> <!-- Modal Content --> </Dialog> </Overlay>
Grid (später)
Zeilen und Spalten definieren Controls in Zellen platzieren
Anchoring-Precedence
Reihenfolge der Layout-Berechnung:
1. Container Layout (wenn explizit) └─ Stack/Grid/Dock/Overlay berechnet Child-Rects 2. Anchors anwenden └─ Innerhalb des Container-Rects verfeinern └─ Min/Max beachten └─ Margins/Padding erhalten 3. Clipping zuletzt └─ Finale Bounds beschneiden
Scroll und Viewport
Wenn Content größer als Bereich
BEVORZUGT: - ScrollViewer Container verwenden - Content scrollbar machen NICHT als Default: - Text "shrink to fit" PFLICHT: - Controls können in kleinerem Rect rendern (Clip + Ellipsis) - State darf nicht verloren gehen
ScrollViewer Beispiel
<ScrollViewer Anchors="Left,Top,Right,Bottom"> <Stack Orientation="Vertical"> <!-- Lange Liste von Controls --> </Stack> </ScrollViewer>
Focus unter Reflow
PFLICHT: - Focus wird über Control-Identität getrackt (nicht Screen-Position) - Nach Reflow: - Wenn fokussiertes Control noch fokussierbar und sichtbar → behalten - Sonst: Fallback auf nächstes fokussierbares Sibling in Focus-Order
Focus-Stabilität
procedure TLayoutEngine.ApplyReflow; var PreviousFocus: TWvdSControl; begin (* Focus merken *) PreviousFocus := FocusManager.FocusedControl; (* Layout neu berechnen *) MeasureAndArrange(RootControl); (* Focus wiederherstellen *) if (PreviousFocus <> nil) and PreviousFocus.CanFocus and PreviousFocus.IsVisible then FocusManager.SetFocus(PreviousFocus) else FocusManager.FocusNextAvailable; end;
Verifikation
Resize-Tests
[ ] Narrow ↔ Wide wiederholt: kein Flicker [ ] Cursor nicht korrupt nach Resize [ ] Focus bleibt auf gleichem Control [ ] Anchored Stretch Controls überlappen nicht [ ] Popups/Overlays bleiben in Screen Bounds
Breakpoint-Tests
[ ] Layout wechselt korrekt bei Breakpoint-Überschreitung [ ] Kein Flicker beim Breakpoint-Wechsel [ ] Alle Breakpoints dokumentiert
Container-Tests
[ ] Stack ordnet Kinder korrekt an [ ] Dock füllt korrekt (Left, Top, Right, Bottom, Fill) [ ] Overlay bleibt in Bounds [ ] Nested Containers funktionieren
PXAML Referenz
Control-Attribute
| Attribut | Werte | Bedeutung |
| Anchors | Left,Top,Right,Bottom | Anchor-Kombinationen |
|---|---|---|
| Margin | „l,t,r,b“ oder „all“ | Äußerer Abstand |
| Padding | „l,t,r,b“ oder „all“ | Innerer Abstand |
| MinWidth | Integer | Minimale Breite |
| MaxWidth | Integer | Maximale Breite |
| MinHeight | Integer | Minimale Höhe |
| MaxHeight | Integer | Maximale Höhe |
Container-Attribute
| Attribut | Werte | Bedeutung |
| ResponsiveMode | Auto, Manual | Automatisches Breakpoint-Handling |
|---|---|---|
| Breakpoints | „w1,w2,…“ | Breakpoint-Breiten |
Siehe auch
Zuletzt geändert: den 29.01.2026 um 15:13