From 0439e21a0582ab892c0e4bfa936c4d62ca2bcc61 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 29 Sep 2026 13:46:49 +0800 Subject: p76: 底部条/槽位药丸化 + 对话/交互面板半透明描边与折行 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DrawHotbar 去掉整条大色块与实心槽位,改半透明条+1px 描边+发丝线,槽位内键位小片与图形并排,选中用 accent 描边;新增 HudLayout.actionLegend(取真实 controlRows 的键位+动作名图例,纯展示不改绑定)。DrawDialogOverlay/DrawPanel 背景改半透明描边语言,禁用近纯黑底。新增 HudLayout.wrapText/wrapLines 按实测宽度折行,DrawPanel 弃用 Substring 截断。新增 P76HotbarPanelTests(4 例);LV_P43_SHOT 昼/夜 + LV_P44_SHOT 对话面板证据 + analyze-p76(四区无实心近黑块、亮像素充足,verdict=PASS)。Desktop 358/358、Kernel 120/120、digest 与 p70 一致。 --- .../LivingVillage.Desktop.Tests.fsproj | 1 + .../P76HotbarPanelTests.fs | 57 ++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/LivingVillage.Desktop.Tests/P76HotbarPanelTests.fs (limited to 'src/LivingVillage.Desktop.Tests') diff --git a/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj b/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj index dc2cb23..c509a0b 100644 --- a/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj +++ b/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj @@ -47,6 +47,7 @@ + diff --git a/src/LivingVillage.Desktop.Tests/P76HotbarPanelTests.fs b/src/LivingVillage.Desktop.Tests/P76HotbarPanelTests.fs new file mode 100644 index 0000000..5a1dd55 --- /dev/null +++ b/src/LivingVillage.Desktop.Tests/P76HotbarPanelTests.fs @@ -0,0 +1,57 @@ +namespace LivingVillage.Desktop.Tests + +open Microsoft.VisualStudio.TestTools.UnitTesting +open LivingVillage.Desktop + +/// P76 回归:底部条/槽位药丸化(键位+图形并排)与面板文本换行不截断。 +[] +type P76HotbarPanelTests () = + + let slot = HudLayout.hotbarSlotRect 1280 720 0 + + [] + member _.KeyChipSitsBesideIconInsideTheSlot () = + let chip = HudLayout.hotbarKeyChipRect slot + let icon = HudLayout.hotbarIconRectBesideKey slot + Assert.IsTrue(chip.X >= slot.X && chip.Right <= slot.Right, "键位小片须在槽内") + Assert.IsTrue(icon.X >= chip.Right, "图形须在键位小片右侧(并排)") + Assert.IsTrue(icon.Right <= slot.Right, "图形须在槽内") + Assert.IsTrue(chip.Y >= slot.Y && chip.Bottom <= slot.Bottom, "键位小片须垂直居中在槽内") + let bar = HudLayout.hotbarBarRect 1280 720 + let hair = HudLayout.hotbarBarHairline bar + Assert.AreEqual(1, hair.Height) + Assert.IsTrue(hair.X >= bar.X && hair.Right <= bar.Right, "发丝线须在条内") + + [] + member _.ActionLegendUsesOnlyRealControlRows () = + let legend = HudLayout.actionLegend MenuState.controlRows + Assert.IsTrue(legend.Length > 0, "图例不得为空") + for row in legend do + Assert.IsTrue( + MenuState.controlRows |> List.exists (fun r -> r.Keys = row.Keys && r.Action = row.Action), + sprintf "图例项 %s/%s 必须是真实 controlRows,不得杜撰" row.Keys row.Action) + Assert.IsFalse(System.String.IsNullOrWhiteSpace row.Keys) + Assert.IsFalse(System.String.IsNullOrWhiteSpace row.Action) + // 键序与预设一致(纯展示,不改绑定)。 + Assert.AreEqual(HudLayout.actionLegendKeys, legend |> List.map (fun r -> r.Keys)) + + [] + member _.PanelWrapNeverExceedsWidthNorDropsCharacters () = + let maxWidth = 240 + let scale = 2 + let text = "今日天气晴好适合下田耕作记得给菜畦浇水并去市集看看货郎的货品是否齐全" + let wrapped = HudLayout.wrapText maxWidth scale text + Assert.IsTrue(wrapped.Length > 1, "长行须折成多行") + for line in wrapped do + Assert.IsTrue(FloatingPrompt.measureWidth line scale <= maxWidth, sprintf "折行超宽: %s" line) + Assert.AreEqual(text, System.String.Concat wrapped) + Assert.AreEqual([ "" ], HudLayout.wrapText maxWidth scale "") + Assert.AreEqual([ "短行" ], HudLayout.wrapText maxWidth scale "短行") + + [] + member _.WrapLinesFlattensWithoutLosingText () = + let source = [ "第一行"; "第二行很长很长很长很长很长很长很长很长很长很长很长很长"; "" ] + let wrapped = HudLayout.wrapLines 160 2 source + Assert.AreEqual(System.String.Concat source, System.String.Concat wrapped) + for line in wrapped do + Assert.IsTrue(FloatingPrompt.measureWidth line 2 <= 160) -- cgit v1.2.3