修复加文本覆写现有轨 + center-only transform 无 auto-fit(#194 #195)#205
Merged
Conversation
added 4 commits
July 6, 2026 22:29
Adds a variant that always inserts a fresh top video track (index 0) and places every text entry there in one undoable transaction, instead of writing into whatever track the caller already has at index 0. 1:1 port of upstream's addTexts all-omitted-trackIndex path (ToolExecutor+Texts.swift:114-121) and addTextClip (EditorViewModel+MediaLibrary.swift:519-558), both of which unconditionally create a new top track rather than reusing an existing one — the gap #194 reports: an existing top track can hold unrelated video/image content that the straight AddTexts path would clear_region over. Entries within the batch still overwrite each other on overlap in start-frame order, matching AddTexts/upstream placeTextClips. Empty entries is an error (a caller mistake), not a no-op like AddCaptions.
) add_texts dispatch now inspects trackIndex across the whole entries batch: - all omitted -> AddTextsAutoTrack (shared new top track, #194 fix) - all set -> existing AddTexts (explicit tracks, overwrite as before) - mixed -> rejected with upstream's exact error text, since a new track at index 0 would shift any explicit indices Also fixes #195: a center-only transform ({centerX, centerY} with no width/height) used to fall through to Transform::default(), filling in identity width/height = 1.0 (full canvas). It now auto-fits the box to the measured text via opentake_domain::TextLayout::natural_size, wrapped at 90% of canvas width — the same measurement path add_captions already uses, and the same 0.9 ratio upstream's parseAddTextTransform hardcodes (ToolExecutor+Texts.swift:38). Omitting transform entirely also auto-fits, centered at (0.5, 0.5) — matches upstream's placeTextClips/addTextClip, which explicitly center + auto-fit a nil transform (EditorViewModel+MediaLibrary.swift:460-493). Passing all four transform fields still overrides without measuring.
New EditRequest::AddTextsAutoTrack variant + TextAutoTrackEntryDto, camelCase serde (startFrame/durationFrames/textStyle) matching the TypeScript EditRequest union and TextAutoTrackEntryReq mirror. Includes a serde round-trip test guarding the camelCase contract, same pattern as the existing addCaptions guard — this repo's #1 bug class is a DTO field that silently fails to deserialize because the wire format didn't match.
The Toolbar "T" button's addTextClip used to reuse the first existing visual track (or create one only if none existed at all), so a top video/image track's content could get overwritten by addTexts' clip placement. It now always calls addTextsAutoTrack, mirroring upstream addTextClip's unconditional insertTrack(at: 0, type: .video) (EditorViewModel+MediaLibrary.swift:519-558) — each call creates its own new top track rather than caching or reusing one.
This was referenced Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
修复两个
add_texts(MCP 工具)/addTextClip(Toolbar "T" 按钮)的 bug:trackIndex时会落到字面 track 0,clear_region把已有内容吃掉。上游insertTrack(at: 0)永远新建顶层轨,从不覆写。{centerX, centerY}时 box 落 identitywidth=1.0 height=1.0(全画布),没有按文本自然尺寸 fit。上游用TextLayout.naturalSize计算。上游对照
addTextsToolExecutor+Texts.swift:42-157(parseAddTextTransform在 18-40 行)addTextClip()EditorViewModel+MediaLibrary.swift:518-558placeTextClips()EditorViewModel+MediaLibrary.swift:454-516三态行为表(
add_texts的trackIndex)trackIndexAddTextsAutoTrack(新增)add_clips)AddTexts(既有)Mixed trackIndex: N of M entries omitted trackIndex. Either set it on every entry or omit it on every entry (to auto-create a shared new track).(与上游文案一致)transform解析(resolve_text_transform,1:1 portparseAddTextTransform)transform{centerX, centerY}{centerX, centerY, width, height}Auto-fit 复用
add_captions已有的度量路径opentake_domain::TextLayout::natural_size,按 90% 画布宽度换行(与ADD_TEXT_MAX_TEXT_WIDTH_RATIO/CAPTION_MAX_TEXT_WIDTH_RATIO同一比例,上游parseAddTextTransform里硬编码同一个0.9)——不是新发明的度量机制。关于 #195 "顺带核实" 项的结论
issue 原文怀疑"省略整个 transform 时实测渲染位置对应 centerY≈0.9(caption 式),与工具文档 'Omit transform to center + auto-fit' 不符"。对照上游源码
EditorViewModel+MediaLibrary.swift:460(TextClipSpec.transformdoc comment:"When nil the box is auto-fit to content and centered on the canvas")以及 493 行实现(Transform(topLeft: ((1-w)/2,(1-h)/2), width: w, height: h),即几何居中),确认工具文档("center")是对的,上游行为也是 center——add_texts省略 transform 时用 (0.5, 0.5)。真机 ~0.9 的观察应该是修复前旧代码Transform::default()(identity 全画布 + 未 auto-fit)叠加渲染细节导致的视觉偏移,不是不同的"预期默认值"。本 PR 的实现(center 0.5/0.5 + auto-fit)与上游一致,无需改文档。add_captions是另一个独立工具,其center_y默认 0.9(字幕贴底),与add_texts的 center 默认互不影响,二者常量也各自独立命名(ADD_TEXT_MAX_TEXT_WIDTH_RATIOvsCAPTION_MAX_TEXT_WIDTH_RATIO)。改动范围
crates/opentake-ops/src/command.rs— 新增EditCommand::AddTextsAutoTrack+TextAutoTrackEntry,单事务插入顶层轨 + 放置全部文本;6 个单测(新轨@0、原轨零变化、undo 单步回滚含新轨、空 entries 报错、非法 duration/startFrame 报错、同批重叠覆写语义)。crates/opentake-agent/src/mcp/dispatch.rs—add_textsdispatch 按 trackIndex 全省略/全指定/混合三态路由;resolve_text_transform+auto_fit_text_transform实现 [HIGH][ops] add_texts 只传 center 时 auto-fit 缺失(box 落 1.0×1.0 全画布;上游 TextLayout.naturalSize) #195 的 auto-fit;8 个单测覆盖三态路由 + 4 种 transform 形状。src-tauri/src/commands.rs—EditRequest::AddTextsAutoTrack+TextAutoTrackEntryDto,camelCase serde;serde round-trip 测试守卫 IPC 边界契约。web/src/lib/types.ts—TextAutoTrackEntryReq镜像 Rust DTO。web/src/store/editActions.ts— Toolbar "T" 的addTextClip()改走addTextsAutoTrack,替换原来的firstVisualTrackIndex覆写路径。web/src/store/editActions.test.ts— 4 个新测试覆盖addTextClip(新轨/空时间线/选中新 clip/连续两次各建各的轨)。验证
cargo fmt --all --check:绿cargo clippy --workspace --all-targets -- -D warnings:绿,零告警cargo test --workspace:全绿(含本 PR 新增的 15 个 Rust 单测)pnpm -C web build:绿pnpm -C web test:44 个测试文件、498 个测试全绿Fixes #194
Fixes #195