From 2851a030db0f0bc5892305fb189a41c97c13578d Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 21 Sep 2026 12:05:26 +0800 Subject: fix(desktop): 标题菜单光标与文字分列不再叠印 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:页面标题行(panelY+24)与首行内容(MenuTopY)同为 y=320 造成两串文字叠印。修复:TitleScreen 布局新增 HeadingY/FirstItemY 分层与独立光标列(CursorX/CursorWidth/TextX),selectionRects 纯函数返回光标与文字矩形,回归测试断言逐行矩形不相交且标题行净空≥32px;渲染改为光标、文字分别绘制。 --- src/LivingVillage.Desktop.Tests/PrototypeTests.fs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/LivingVillage.Desktop.Tests') diff --git a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs index 524573f..c85287f 100644 --- a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs +++ b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs @@ -245,6 +245,22 @@ type PrototypeTests () = Assert.IsTrue(ChineseText.requiredUiLabels |> List.contains "金钱") Assert.IsTrue(ChineseText.requiredUiLabels |> List.contains "精力") + [] + member _.TitleScreenSelectionCursorAndLabelNeverOverprint () = + let layout = TitleScreen.layout 1280 720 + + // Heading must sit fully above the first menu row (no same-line overprint). + Assert.IsTrue(layout.FirstItemY - layout.HeadingY >= 32, sprintf "heading clearance %d" (layout.FirstItemY - layout.HeadingY)) + + // Every menu row: cursor rectangle and label rectangle must be disjoint. + for rowIndex in 0 .. 5 do + let cursor, label = TitleScreen.selectionRects layout rowIndex + Assert.IsTrue(TitleScreen.rectsDisjoint cursor label, sprintf "row %d cursor overlaps label" rowIndex) + Assert.AreEqual(cursor.Y, label.Y) + + // Cursor column leaves real clearance: label starts beyond cursor + margin. + Assert.IsTrue(layout.TextX >= layout.CursorX + layout.CursorWidth) + [] member _.TitleScreenLayoutIsDeterministicAndLayered () = let first = TitleScreen.layout 1280 720 -- cgit v1.2.3