Add parallel resize mode to the UiRoot retained-mode input state machine.
A left-drag starting within ResizeGrip=5px of a Resizable window's edge or
corner resizes it (min-size clamped); interior drags on a Draggable window
still reposition it.
Changes:
- UiElement: Resizable, MinWidth, MinHeight properties
- UiRoot: ResizeEdges flags enum; _resizeTarget state fields; FindWindow
(replaces FindDraggable, matches Draggable||Resizable); HitEdges (static,
internal, testable); ResizeRect (static, public, testable); OnMouseDown
checks edge-grip before move; OnMouseMove resize branch precedes move;
OnMouseUp clears _resizeTarget
- UiNineSlicePanel: Resizable = true (retail windows are resizable)
- UiRootInputTests: 4 new tests — ResizeRect_RightBottom, ResizeRect_LeftTop
(min-clamp + origin shift), HitEdges_DetectsCornerAndInteriorNone,
EdgeDrag_ResizesPanel_InteriorDragMoves (full integration path)
Note on test coordinate: right-edge grab uses x=298 (2px inside the panel's
hit-test boundary) rather than x=300 (exactly at edge, misses OnHitTest's
strict `<` check). This is intentional — the grip zone extends inward from
the edge boundary, so a click 2px inside correctly lands in both the
hit-test rect AND the resize-grip zone.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>