Skip to content

Make the rail's strip keys deform too - #118

Merged
LynxTWO merged 1 commit into
masterfrom
feat/rail-keys-deform
Aug 24, 2026
Merged

LynxTWO merged 1 commit into
masterfrom
feat/rail-keys-deform

Conversation

@LynxTWO

@LynxTWO LynxTWO commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Closes the D-080 (4) debt. The ten navigation strip keys now take the same soft-body press as every other key.

They were left out for the reason D-080 itself predicted: Avalonia's bare Button selector matches by exact type, RailStripKey derives from Border, so the most-clicked surface in the app was the only rigid one.

Neither half was large.

  • The press binding and renderer took Button and used nothing a Button provides - AddHandler, Bounds and GetPosition are all on Control. Widening two parameter types was the entire change there.
  • RailStripKey drew itself as a single Border. It now builds the same layers the XAML template builds (keyRecess, keyFace, keyDip) under the names the shared renderer looks up, with the glyph inside the face so it shears with the rubber per D-080 (2).

No keySeam layer on the rail key, deliberately. Its housing lamp is composed into its own BoxShadow because the control is code-built rather than styled, and naming a seam layer would hand one property to two writers - the renderer clears it on release and would take the hover glow with it. Same trap as D-084 (2), one property along; not creating the collision was cheaper than arbitrating it.

Guarded by test, because this failure is silent. The renderer finds layers by name: rename or restructure one and nothing throws, nothing warns, no other test fails, and the keys just stop deforming. Three tests bind the parts, the glyph's parentage, and that a held key carries a genuinely projective matrix rather than a flattened affine one.

197 green with the gate off (how CI runs); verified with CUETOOLS_SOFTBODY=1 that a held key produces a MatrixTransform with live perspective terms, and rendered the strip in both themes to confirm the restructure kept the approved icon-sheet look.

D-080 scoped these in from the start and they were the one surface
left out, for the reason that decision itself predicted: Avalonia's
bare Button selector matches by exact type, RailStripKey is a Border,
and so the most-clicked thing in the app was the only thing that had
stopped moving.

Neither half of the fix was large. The press binding and the renderer
took a Button and used nothing a Button provides - AddHandler, Bounds
and GetPosition all live on Control - so widening two parameter types
was the whole change on that side. RailStripKey drew itself as one
Border; it now builds the same layers the XAML template builds, under
the names the renderer looks up, with the glyph inside the face so it
shears with the rubber instead of floating over it.

No seam layer on the rail key, on purpose. Its housing lamp is
composed into its own BoxShadow because the control is code-built
rather than styled, and naming a seam layer would hand one property to
two writers - the renderer clears it on release and would take the
hover glow with it. That is a trap we have already paid for once, one
property along, and not creating the collision was cheaper than
arbitrating it.

Guarded by test, because this failure is silent: the renderer finds
its layers by name, so a rename breaks deformation with nothing
thrown, nothing warned and no other test failing.
@LynxTWO
LynxTWO merged commit c2b1b01 into master Aug 24, 2026
6 checks passed
@LynxTWO
LynxTWO deleted the feat/rail-keys-deform branch August 24, 2026 03:56
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