Skip to content

TUI stage 3: render tree#32

Merged
xvrh merged 25 commits into
masterfrom
claude/silly-pascal-81d3b6
May 15, 2026
Merged

TUI stage 3: render tree#32
xvrh merged 25 commits into
masterfrom
claude/silly-pascal-81d3b6

Conversation

@xvrh

@xvrh xvrh commented May 15, 2026

Copy link
Copy Markdown
Owner

Summary

Stage 3 of the Flutter-style terminal UI framework in app/lib/src/tui/ — a cell-based transcription of Flutter's render layer. Layout reuses Flutter's box protocol (constraints down, sizes up); the only substitution is the unit: terminal cells instead of pixels. Render objects paint through the stage 2 Painter.

  • Layout protocolBoxConstraints (cell-based min/max width & height with the full algebra: tight/tightFor/loose/constrain/deflate/loosen/enforce), RenderObject/RenderBox, the four intrinsic-dimension methods, and EdgeInsets.
  • Dirty-trackingPipelineOwner with depth-sorted flushLayout; markNeedsLayout localizes re-layout to the nearest relayout boundary. markNeedsPaint is whole-tree (no layer model yet — documented limitation).
  • Render objectsRenderText (leaf), RenderPadding, RenderConstrainedBox, RenderDecoratedBox (border + fill), RenderFlex (the Row/Column mechanism: two-pass layout, flex factors with FlexFit, all alignments, and a Bresenham-style integer space split that tiles the parent exactly), and RenderTuiView (the root, bridging the tree to Terminal.draw).
  • Demoapp/examples/tui/render_tree_demo.dart: a multi-panel screen (header / two bordered flex panels / footer) with key-driven mutation and resize.

All stage 3 code lives in one library app/lib/src/tui/render/render.dart composed of part files. Design spec and implementation plan are in docs/superpowers/.

Built task-by-task with TDD; each task had spec-compliance and code-quality review.

Test plan

  • cd app && flutter test test/tui/ — 225 tests pass (81 new under test/tui/render/)
  • flutter analyze — clean
  • dart tool/prepare_submit.dart — no diff
  • Manual smoke: run cd app && dart run examples/tui/render_tree_demo.dart in a real terminal — header bar, two bordered panels (left flex 1, right flex 2) with wrapped text, footer; keypress updates the left panel only; resize re-lays the screen; q exits cleanly. (Not runnable in a non-tty console such as the IDE run window.)

🤖 Generated with Claude Code

xvrh and others added 25 commits May 15, 2026 17:16
Cell-based transcription of Flutter's render layer: RenderObject/RenderBox,
BoxConstraints, intrinsics, dirty-tracking via PipelineOwner, and a starter
render-object set (Text, Padding, ConstrainedBox, Flex, DecoratedBox).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A box that receives tight constraints cannot change size on re-layout, so
it is its own relayout boundary — essential for localizing re-layout (and
for stage 4 panels). Fix the boundary test to cover both the tight case
(self boundary) and the non-tight case (dirty bubbles to the parent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Text

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…DecoratedBox

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Row/Column mechanism: two-pass layout, flex factors with FlexFit,
main/cross alignment, and a Bresenham-style integer space split that tiles
the parent exactly. Tests adjusted from the plan draft: the single-flex
test now passes FlexFit.tight (a loose flex child may stay smaller), and
two CrossAxisAlignment tests drop an unused local.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…erFlex tests

Also fixes the _splitProportional doc comment to accurately describe the
cumulative-floor (Bresenham) algorithm instead of claiming front-to-back
remainder distribution.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t for RenderTuiView

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@xvrh
xvrh merged commit 04a7edd into master May 15, 2026
1 check passed
@xvrh
xvrh deleted the claude/silly-pascal-81d3b6 branch May 15, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant