Skip to content

Add TransformBox, move and scale handles on a rectangle in its own frame - #593

Merged
matt-edmondson merged 2 commits into
mainfrom
claude/project-thread-kkg9ou
Oct 7, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
claude/project-thread-kkg9ou

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Requested by Matt · project thread

Before: there was no widget for dragging a rectangle with handles through an arbitrary transform. CropOverlay is a crop in image pixels with its own rotation, and ImageGui kept its own crop handles locally until a second consumer turned up.

After: ImGuiWidgets.TransformBox draws a rectangle with corner and edge handles in its own frame, through a caller-supplied Matrix3x2, and lets the user move it, resize it and scale it. A crop passes the image's rectangle on screen; a layer passes its placement composed with that, so its handles sit on its turned corners. ImageGui's M5c layer arranging is the second consumer.

How: hit-testing happens on screen (the grab radius is screen pixels however the frame is stretched or turned, and shrinks inside a box too small for its handles so it keeps a body), while drags are measured in the frame as it was at the press, so a caller whose edit moves the frame gets a stable answer. Corners are free by default or uniform with UniformCorners (Shift inverts), and a uniform corner scales by the pointer's travel along the diagonal on screen. The box submits its hit area only over itself or while held, so a press elsewhere still reaches an ImageCanvas pan underneath. TransformBoxOptions.Resize lets a caller replace the built-in rule, which is how a crop keeps its aspect presets. The rules live in the ImGui-free TransformBoxState.

Comes with state unit tests (19), an isolation suite (10), a widgets demo section with a UI test, a gallery tile, and README/CLAUDE.md entries. Locally: Widgets.Tests and the full ImGui.Widgets.UITests suite (680) pass, WidgetGallery.UITests pass, and --check reports every widget has a tile.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HSx9oajT9nHUKVaNDS3pfi


Generated by Claude Code

…ame [minor]

A rectangle with corner and edge handles, held in a frame of the caller's
choosing and drawn through a Matrix3x2 to the screen. Dragging the body moves
it, an edge moves that edge, and a corner moves both edges or scales about the
opposite corner. Hit-testing is on screen, so the grab radius is the same however
the frame is stretched or turned; the drag is measured in the frame as it was at
the press, so a caller whose edit moves the frame gets a stable answer. The box
submits its hit area only over itself, so a press elsewhere still pans a canvas
underneath, and a caller's own rule can replace the built-in resize.

This is the rect-with-handles ImageGui's crop kept local until a second consumer
existed; its layer arranging is that consumer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HSx9oajT9nHUKVaNDS3pfi
@matt-edmondson matt-edmondson self-assigned this Oct 7, 2026
Comment thread ImGui.Widgets/TransformBoxState.cs Fixed
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HSx9oajT9nHUKVaNDS3pfi
@sonarqubecloud

sonarqubecloud Bot commented Oct 7, 2026

Copy link
Copy Markdown

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.

2 participants