From 97ed504a880f67ffffcb3666318556c6b9c68808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 1 Sep 2026 19:46:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B6=8A=E7=95=8C=E9=94=9A?= =?UTF-8?q?=E7=82=B9=E6=8C=81=E4=B9=85=E5=8C=96=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除持久化层对有序越界 anchor 的错误范围限制 同步移除编辑器中的越界锚点误导警告 新增越界 anchor 保存加载往返回归测试 --- .../src-tauri/src/ui_editor/persistence.rs | 38 ++++++++++++++----- .../Inspector/Transform/TransformEditor.tsx | 2 - 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/persistence.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/persistence.rs index e6c513f11..04b72c0b3 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/persistence.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/persistence.rs @@ -678,16 +678,6 @@ fn validate_node( { return Err("UI 节点 Transform 必须是有限数值".to_string()); } - if node - .layout - .transform - .anchor_min - .iter() - .chain(node.layout.transform.anchor_max.iter()) - .any(|value| *value < 0.0 || *value > 1.0) - { - return Err("UI 节点 Transform 的 anchor 必须处于 0..=1 范围".to_string()); - } if node .layout .transform @@ -1053,6 +1043,34 @@ mod tests { assert_eq!(loaded.state, state); } + #[test] + fn preserves_ordered_out_of_range_transform_anchors() { + let (directory, asset_id) = fixture(); + let mut state = state_with_sprite_and_dragged_transform(); + let transform = &mut state.ui_trees[0].root.children[0].layout.transform; + transform.anchor_min = Vector2::new(-0.25, -0.5); + transform.anchor_max = Vector2::new(1.5, 1.25); + + let saved = save_ui_design_state_at(input(directory.path(), &asset_id, 0, state.clone())) + .expect("save ordered out-of-range anchors"); + assert!(matches!( + saved, + SaveUiDesignStateResult::Saved { + revision: 1, + state: ref installed, + .. + } if installed == &state + )); + + let loaded = load_ui_design_state_at(LoadUiDesignStateInput { + project_path: directory.path().to_string_lossy().into_owned(), + expected_project_id: PROJECT_ID.to_string(), + asset_id, + }) + .expect("load ordered out-of-range anchors"); + assert_eq!(loaded.state, state); + } + #[test] fn rejects_inverted_transform_anchors() { let state: State = serde_json::from_value(serde_json::json!({ diff --git a/apps/ai-game-creator-shell/src/view/ui-editor/components/Inspector/Transform/TransformEditor.tsx b/apps/ai-game-creator-shell/src/view/ui-editor/components/Inspector/Transform/TransformEditor.tsx index 1e50b09d2..85039f389 100644 --- a/apps/ai-game-creator-shell/src/view/ui-editor/components/Inspector/Transform/TransformEditor.tsx +++ b/apps/ai-game-creator-shell/src/view/ui-editor/components/Inspector/Transform/TransformEditor.tsx @@ -367,8 +367,6 @@ export function TransformEditor({ const warning = transform.anchor_min[0] > transform.anchor_max[0] || transform.anchor_min[1] > transform.anchor_max[1] || - transform.anchor_min.some((value) => value < 0 || value > 1) || - transform.anchor_max.some((value) => value < 0 || value > 1) || geometry?.invalid; return (