Skip to content

Inspector 编辑:动画值可编辑 + Transform Reset(1:1 上游)#177

Merged
appergb merged 3 commits into
mainfrom
feat/inspector-keyframe-editing
Jul 2, 2026
Merged

Inspector 编辑:动画值可编辑 + Transform Reset(1:1 上游)#177
appergb merged 3 commits into
mainfrom
feat/inspector-keyframe-editing

Conversation

@appergb

@appergb appergb commented Jul 2, 2026

Copy link
Copy Markdown
Owner

接替被自动关闭的 #173(其 base 分支随 #172 合并被删)。已 rebase 到 main 并解决与 #176 的测试文件冲突。

  • UpsertKeyframe 命令(Rust+IPC camelCase+TS,属性有轨道时在播放头按显式值 upsert,镜像上游 write)
  • Inspector 7 个动画属性字段从只读改可编辑;seed 用原始轨道采样(liveVolumeKfLinearAt/rawOpacityAt,对齐上游,避免把静态增益/淡变烘进关键帧)+ 3 回归测试
  • Transform Reset 按钮(EditCommand::ResetTransform:transform→identity、opacity→1、清 4 轨道、fades→0,crop 不动,1:1 上游 transformHeader.onReset)

本地全绿:cargo fmt/clippy -D warnings/test(274);pnpm build/test(285)。

baiqing added 3 commits July 2, 2026 08:21
…playhead

Mirror upstream write<Property>'s upsert branch: when a property already has a
keyframe track, editing its value should upsert a keyframe at the playhead —
not fall back to read-only (today's Inspector gap). Distinct from StampKeyframe
(samples the current value) and SetClipProperties (clears tracks).

- command.rs: EditCommand::UpsertKeyframe { clip_id, property, frame, value }
  + KeyframeValue{Scalar,Pair,Crop}; validates the property-value pairing
  (Opacity/Volume/Rotation=Scalar, Position/Scale=Pair, Crop=Crop; Volume in
  dB) then upserts at the clip-relative offset. 6 apply tests.
- commands.rs: IPC DTO KeyframeValueDto (tagged "kind", camelCase) -> KeyframeValue;
  3 raw-JSON camelCase serde round-trip tests guarding the IPC boundary.
- types.ts / editActions.ts: KeyframeValueReq + upsertKeyframe() wrapper.

Step A of the Inspector animation-editing cluster; frontend wiring (step B) follows.
… the playhead

Close the T2-5 gap: when a clip property already had a keyframe track, its
Inspector field was rendered READ-ONLY. Upstream keeps it editable and upserts a
keyframe at the playhead on edit (writeVolume/writeScale/writePosition/...). Wire
the 7 animated fields (Volume, Scale, Rotation, Opacity, Position X/Y, Crop edges)
to the existing upsertKeyframe() through a pure value-mapping helper.

- keyframeValue.ts: pure (field value, sampled state) -> KeyframeValueReq per
  property (Opacity/Rotation/Volume=scalar, Scale/Position=AnimPair {a,b},
  Crop=crop; Scale reuses resizeTransformKeepingSourceAspect so height derives
  identically to the static path). 11 unit tests.
- Inspector.tsx: each animated field is now an editable ScrubbableNumberField
  (seeded from the sampled-at-playhead value) whose onCommit branches
  animated -> upsertKeyframe / static -> the existing commit. AnimatedHint kept;
  the now-dead ReadOnlyValue removed.
- clip.ts: seed animated Volume/Opacity from the RAW track sample
  (liveVolumeKfLinearAt / rawOpacityAt), NOT the composited volumeAt/opacityAt —
  matching upstream InspectorView (liveVolumeKfDb / rawOpacityAt) so editing
  upserts the authored value instead of baking in the static gain / fade
  envelope. 3 regression tests.

Frontend only; the UpsertKeyframe command/IPC/wrapper already landed in 1c7c7bd.
Verified: pnpm build (tsc) clean; pnpm test 240 passed (+14 new).
…ades (upstream parity)

Port upstream InspectorView.transformHeader's onReset as a 1:1 replica of its
exact field set: reset the selected clip's transform to identity, opacity to 1,
clear the opacity/position/scale/rotation keyframe tracks, and zero both fades
(interpolation back to linear). Crop is untouched (a separate Inspector section).

- command.rs: EditCommand::ResetTransform { clip_ids } — a dedicated command so
  the whole reset is one atomic undo step (mirrors SetColorGrade/SetEffects shape
  and reuses set_clip_effect_field for up-front id validation), NOT a chain of
  SetClipProperties + SetKeyframes which would break atomicity. 6 tests: clears
  exactly the four tracks, crop survives, other clips untouched, undoable,
  missing/empty-ids error with no change, and no-op-when-already-default reports
  unchanged.
- commands.rs: camelCase EditRequest::ResetTransform { clipIds } DTO + serde
  round-trip test guarding the IPC boundary.
- types.ts / editActions.ts: resetTransform(clipIds) action (empty-guarded).
- Inspector.tsx: RotateCcw HoverButton in the Transform section header,
  right-aligned to match upstream's arrow.counterclockwise placement.
- dict.ts: inspector.action.resetTransform (zh/en).

Verified: cargo fmt/clippy -D warnings clean; ops reset tests 6/6 + tauri serde
test pass; pnpm build clean; pnpm test 240 passed.
@appergb appergb merged commit 008dcff into main Jul 2, 2026
2 checks passed
@appergb appergb deleted the feat/inspector-keyframe-editing branch July 2, 2026 00:30
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