Overview
Follow-up to #380 / PR #381 — the curve editor's free-form tangent handle drag + resample-into-TransformKeyFrame.
D3a (#379) shipped the read-only view; D3b (#381) shipped per-channel values + the interp-mode picker. This issue tracks the remaining editing affordances:
- Tangent handle drag — mouse-drag the tangent stubs the curve editor already paints. Updates
CurveEditModel.setTangents(). Auto-promotes the keyframe to Bezier mode (the model already does this).
- Keyframe value drag — Y-axis drag on a keyframe square edits its channel value via
setKeyframeValue; X-axis drag retimes via the existing moveKeyframe. Shift-constrains to one axis.
- Resampler — when a tangent / value / mode changes, walk the affected curve segment in N samples/sec and write the result back into the underlying TransformKeyFrames so Ogre playback matches the curve. N = 30 default, bumped to 60 around high-curvature regions, capped at 200 keyframes/segment.
- Resample undo — single
ResampleCurveCommand per gesture so Ctrl+Z reverts the whole edit.
Why this is a separate issue
The curve editor is a Canvas2D paint, so handle MouseAreas have to be placed dynamically at the painted positions. Doing this correctly under arbitrary curve shapes (and pan/zoom transforms) is a non-trivial QML refactor — likely worth its own PR rather than expanding D3b.
Acceptance criteria
Closes Phase 5's animation work once it lands.
Overview
Follow-up to #380 / PR #381 — the curve editor's free-form tangent handle drag + resample-into-TransformKeyFrame.
D3a (#379) shipped the read-only view; D3b (#381) shipped per-channel values + the interp-mode picker. This issue tracks the remaining editing affordances:
CurveEditModel.setTangents(). Auto-promotes the keyframe to Bezier mode (the model already does this).setKeyframeValue; X-axis drag retimes via the existingmoveKeyframe. Shift-constrains to one axis.ResampleCurveCommandper gesture so Ctrl+Z reverts the whole edit.Why this is a separate issue
The curve editor is a Canvas2D paint, so handle MouseAreas have to be placed dynamically at the painted positions. Doing this correctly under arbitrary curve shapes (and pan/zoom transforms) is a non-trivial QML refactor — likely worth its own PR rather than expanding D3b.
Acceptance criteria
Plan (#260)
Closes Phase 5's animation work once it lands.