Overlay generator (pure, tested) — RioJoy.Core/Overlay:
- FontFitter ports the legacy calc-fontsize auto-fit search (validated against a
brute-force oracle); OverlayLayoutEngine ports create-data-layer's fit + h/v
justification and adds per-region 90 deg CCW rotation; OverlayTemplate/Region +
OverlayTemplateStore hold cell geometry/colour/rotation (regions.json).
- GoobieDataImporter parses the legacy .data label sheet into label rows.
- src/RioJoy.Overlay: SkiaSharp rasterizer (SkiaTextMeasurer shared with the engine
so measured layout == drawn output; SkiaOverlayRenderer -> PNG;
ProfileWallpaperGenerator). Verified end-to-end on the real cockpit art
(regions.json + riojoy.png + TEST.data) by OverlayRenderIntegrationTests.
- RioJoy.Tray/WallpaperApplier applies via SystemParametersInfo; RioCoordinator
generates+applies on profile activation (opt-in via AppConfig.OverlayTemplatePath).
Region geometry — tools/XcfRegionExtract parses riojoy.xcf (a GIMP-format binary
reader, no GIMP needed) into the 119-cell regions.json: per-layer offsets/size/
font/colour, with 90 deg CCW rotation on a-00 + b-10..b-1F. Base image riojoy.png.
NOTE: the wallpaper positions are a VGA chroma-split display artifact (6 displays),
not the cockpit's logical layout.
Mapping editor (first cut) — RioJoy.Tray/Editor/ProfileEditorForm renders the
config sheet's logical grid (SheetLayout parses the sheet CSV export). The iRIO
word is edited via ButtonBinding <-> RioMapEntry.Create (no hex bit-twiddling), with
a context-sensitive picker: keyboard keys by name (KeyCatalog VK names), joystick
Button N, hat direction, mouse/RIO-command enum names; modifiers only for keyboard.
Opened from the tray ("Edit profile..."). The sheet-grid layout is a starting point
that needs rework from a better-formatted source.
~220 xUnit tests green. Docs (PLAN.md, README) updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
1.7 KiB
C#
54 lines
1.7 KiB
C#
using RioJoy.Core.Overlay;
|
|
using Xunit;
|
|
|
|
namespace RioJoy.Core.Tests.Overlay;
|
|
|
|
public class OverlayTemplateStoreTests
|
|
{
|
|
[Fact]
|
|
public void RoundTrips_GeometryAndOverrides()
|
|
{
|
|
var template = new OverlayTemplate
|
|
{
|
|
BaseImagePath = "cockpit.png",
|
|
Width = 1920,
|
|
Height = 1080,
|
|
Regions =
|
|
{
|
|
new OverlayRegion { Name = "b-00", X = 10, Y = 20, Width = 80, Height = 24, FontFamily = "Consolas", FontSizePx = 18 },
|
|
new OverlayRegion { Name = "b-41", X = 5, Y = 7, Width = 60, Height = 30, HJust = OverlayHJust.Right, VJust = OverlayVJust.Bottom },
|
|
},
|
|
};
|
|
|
|
OverlayTemplate back = OverlayTemplateStore.Deserialize(OverlayTemplateStore.Serialize(template));
|
|
|
|
Assert.Equal(1920, back.Width);
|
|
Assert.Equal(2, back.Regions.Count);
|
|
|
|
OverlayRegion? r0 = back.FindRegion("b-00");
|
|
Assert.NotNull(r0);
|
|
Assert.Equal(80, r0!.Width, 6);
|
|
Assert.Equal("Consolas", r0.FontFamily);
|
|
Assert.Null(r0.HJust);
|
|
|
|
OverlayRegion? r1 = back.FindRegion("B-41"); // case-insensitive lookup
|
|
Assert.NotNull(r1);
|
|
Assert.Equal(OverlayHJust.Right, r1!.HJust);
|
|
Assert.Equal(OverlayVJust.Bottom, r1.VJust);
|
|
}
|
|
|
|
[Fact]
|
|
public void Serialize_WritesEnumsAsStrings()
|
|
{
|
|
var template = new OverlayTemplate
|
|
{
|
|
Regions = { new OverlayRegion { Name = "x", HJust = OverlayHJust.Center } },
|
|
};
|
|
|
|
string json = OverlayTemplateStore.Serialize(template);
|
|
|
|
Assert.Contains("\"Center\"", json);
|
|
Assert.DoesNotContain("\"HJust\": 1", json);
|
|
}
|
|
}
|